STM32F767ZI External Interrupt Handling












0















I'm attempting to create a proper SPI slave interface for an AD7768-4 ADC. The ADC has a SPI interface, but it doesn't output the conversions via SPI. Instead, there are data outputs that are clocked out on individual GPIO pins. So I basically need to bit-bang data, and output to SPI to get a proper slave SPI interface. Please don't ask why I'm doing it this way, it was assigned to me.



The issue I'm having is with the interrupts. I'm using the STM32F767ZI processor - it runs at 216 MHz, and my ADC data MUST BE clocked out at 20MHz. I've set up my NMIs but what I'm not seeing is where the system calls or points to the interrupt handler.



I used the STMCubeMX software to assign pins and generate the setup code, and in the stm32F7xx.c file, it shows the NMI_Handler() function, but I don't see a pointer to it anywhere in the system files. I also found void HAL_GPIO_EXTI_IRQHandler() function in STM32F7xx_hal_gpio.c, which appears to check if the pin is asserted, and clears any pending bits, but it doesn't reset the interrupt flag, or check it, and again, I see no pointer to this function.



To more thoroughly complicate things, I have 10 clock cycles to determine which flag is set (1 of two at a time), reset it, incerment a variable, and move data from the GPIO registers. I believe this is possible, but again, I'm uncertain of what the system is doing as soon as the interrupt is tripped.



Does anyone have any experience in working with external interrupts on this processor that could shed some light on how this particular system handles things? Again - 10 clock cycles to do what I need to... moving data should only take me 1-2 clock cycles, leaving me 8 to handle interrupts...



EDIT:



We changed the DCLK speed to 5.12 MHz (20.48 MHz MCLK/4) because at 2.56 MHz we had exactly 12.5 microseconds to pipe data out and set up for the next DRDY pulse, and 80 kHz speed gives us exactly zero margin. At 5.12 MHz, I have 41 clock cycles to run the interrupt routine, which I can reduce slightly if I skip checking the second flag and just handle incoming data. But I feel I must use the DRDY flag check at least, and use the routine to enable the second interrupt otherwise I'll be constantly interrupting because DCLK on the ADC is always running. This allows me 6.12 microseconds to read in the data, and 6.25 microseconds to shuffle it out before the next DRDY pulse. I should be able to do that at 32 MHz SPI clock (slave) but will most likely do it at 50MHz. This is my current interrupt code:



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);
}
}
}


I am still concerned about clock cycles, and I believe I can get away with only checking the DRDY flag if I operate on the presumption that the only other EXTI flag that will trip is for the clock pin. Although I question how this will work if SYS_TICK is running in the background... I'll have to find out.



We're investigating a faster processor to handle the bit-banging, but right now, it looks like the PI3 won't be able to handle it if it's running Linux, and I'm unaware of too many faster processors that run either a very small reliable RTOS, or can be bare metal programmed in a pinch...










share|improve this question

























  • Consider usage of serial audio interface (SAI) in slave mode with PCM/DSP frames (use ADC DRDY as FS). You can use two SAI channels (2*24 bit slots per channel) if ADC can out samples via DATA0 and DATA1.

    – ReAl
    Nov 14 '18 at 13:46











  • @ReAl - I'm reading DATA),1,2,3 simultaneously. And it's piped in at 20MHz. Not sure SAI can handle that. Thanks though!

    – Jedi Engineer
    Nov 14 '18 at 15:00











  • SAI has two 1-bit channels. One's can connect in parallel frame start (FS) and clock inputs while use data inputs separately, so SAI can receive maximum two data streams from ADC.

    – ReAl
    Nov 14 '18 at 15:25











  • @ReAl, as I indicated before, I have four data inputs to read simultaneously - Data0, Data1, Data2, and Data3. I also have the data clock to follow. It wouldn't work. We explored that already. Thanks Though!

    – Jedi Engineer
    Nov 14 '18 at 15:59











  • @JediEngineer There are 2 SAI controllers with 2 channels each

    – berendi
    Nov 15 '18 at 21:29
















0















I'm attempting to create a proper SPI slave interface for an AD7768-4 ADC. The ADC has a SPI interface, but it doesn't output the conversions via SPI. Instead, there are data outputs that are clocked out on individual GPIO pins. So I basically need to bit-bang data, and output to SPI to get a proper slave SPI interface. Please don't ask why I'm doing it this way, it was assigned to me.



The issue I'm having is with the interrupts. I'm using the STM32F767ZI processor - it runs at 216 MHz, and my ADC data MUST BE clocked out at 20MHz. I've set up my NMIs but what I'm not seeing is where the system calls or points to the interrupt handler.



I used the STMCubeMX software to assign pins and generate the setup code, and in the stm32F7xx.c file, it shows the NMI_Handler() function, but I don't see a pointer to it anywhere in the system files. I also found void HAL_GPIO_EXTI_IRQHandler() function in STM32F7xx_hal_gpio.c, which appears to check if the pin is asserted, and clears any pending bits, but it doesn't reset the interrupt flag, or check it, and again, I see no pointer to this function.



To more thoroughly complicate things, I have 10 clock cycles to determine which flag is set (1 of two at a time), reset it, incerment a variable, and move data from the GPIO registers. I believe this is possible, but again, I'm uncertain of what the system is doing as soon as the interrupt is tripped.



Does anyone have any experience in working with external interrupts on this processor that could shed some light on how this particular system handles things? Again - 10 clock cycles to do what I need to... moving data should only take me 1-2 clock cycles, leaving me 8 to handle interrupts...



EDIT:



We changed the DCLK speed to 5.12 MHz (20.48 MHz MCLK/4) because at 2.56 MHz we had exactly 12.5 microseconds to pipe data out and set up for the next DRDY pulse, and 80 kHz speed gives us exactly zero margin. At 5.12 MHz, I have 41 clock cycles to run the interrupt routine, which I can reduce slightly if I skip checking the second flag and just handle incoming data. But I feel I must use the DRDY flag check at least, and use the routine to enable the second interrupt otherwise I'll be constantly interrupting because DCLK on the ADC is always running. This allows me 6.12 microseconds to read in the data, and 6.25 microseconds to shuffle it out before the next DRDY pulse. I should be able to do that at 32 MHz SPI clock (slave) but will most likely do it at 50MHz. This is my current interrupt code:



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);
}
}
}


I am still concerned about clock cycles, and I believe I can get away with only checking the DRDY flag if I operate on the presumption that the only other EXTI flag that will trip is for the clock pin. Although I question how this will work if SYS_TICK is running in the background... I'll have to find out.



We're investigating a faster processor to handle the bit-banging, but right now, it looks like the PI3 won't be able to handle it if it's running Linux, and I'm unaware of too many faster processors that run either a very small reliable RTOS, or can be bare metal programmed in a pinch...










share|improve this question

























  • Consider usage of serial audio interface (SAI) in slave mode with PCM/DSP frames (use ADC DRDY as FS). You can use two SAI channels (2*24 bit slots per channel) if ADC can out samples via DATA0 and DATA1.

    – ReAl
    Nov 14 '18 at 13:46











  • @ReAl - I'm reading DATA),1,2,3 simultaneously. And it's piped in at 20MHz. Not sure SAI can handle that. Thanks though!

    – Jedi Engineer
    Nov 14 '18 at 15:00











  • SAI has two 1-bit channels. One's can connect in parallel frame start (FS) and clock inputs while use data inputs separately, so SAI can receive maximum two data streams from ADC.

    – ReAl
    Nov 14 '18 at 15:25











  • @ReAl, as I indicated before, I have four data inputs to read simultaneously - Data0, Data1, Data2, and Data3. I also have the data clock to follow. It wouldn't work. We explored that already. Thanks Though!

    – Jedi Engineer
    Nov 14 '18 at 15:59











  • @JediEngineer There are 2 SAI controllers with 2 channels each

    – berendi
    Nov 15 '18 at 21:29














0












0








0








I'm attempting to create a proper SPI slave interface for an AD7768-4 ADC. The ADC has a SPI interface, but it doesn't output the conversions via SPI. Instead, there are data outputs that are clocked out on individual GPIO pins. So I basically need to bit-bang data, and output to SPI to get a proper slave SPI interface. Please don't ask why I'm doing it this way, it was assigned to me.



The issue I'm having is with the interrupts. I'm using the STM32F767ZI processor - it runs at 216 MHz, and my ADC data MUST BE clocked out at 20MHz. I've set up my NMIs but what I'm not seeing is where the system calls or points to the interrupt handler.



I used the STMCubeMX software to assign pins and generate the setup code, and in the stm32F7xx.c file, it shows the NMI_Handler() function, but I don't see a pointer to it anywhere in the system files. I also found void HAL_GPIO_EXTI_IRQHandler() function in STM32F7xx_hal_gpio.c, which appears to check if the pin is asserted, and clears any pending bits, but it doesn't reset the interrupt flag, or check it, and again, I see no pointer to this function.



To more thoroughly complicate things, I have 10 clock cycles to determine which flag is set (1 of two at a time), reset it, incerment a variable, and move data from the GPIO registers. I believe this is possible, but again, I'm uncertain of what the system is doing as soon as the interrupt is tripped.



Does anyone have any experience in working with external interrupts on this processor that could shed some light on how this particular system handles things? Again - 10 clock cycles to do what I need to... moving data should only take me 1-2 clock cycles, leaving me 8 to handle interrupts...



EDIT:



We changed the DCLK speed to 5.12 MHz (20.48 MHz MCLK/4) because at 2.56 MHz we had exactly 12.5 microseconds to pipe data out and set up for the next DRDY pulse, and 80 kHz speed gives us exactly zero margin. At 5.12 MHz, I have 41 clock cycles to run the interrupt routine, which I can reduce slightly if I skip checking the second flag and just handle incoming data. But I feel I must use the DRDY flag check at least, and use the routine to enable the second interrupt otherwise I'll be constantly interrupting because DCLK on the ADC is always running. This allows me 6.12 microseconds to read in the data, and 6.25 microseconds to shuffle it out before the next DRDY pulse. I should be able to do that at 32 MHz SPI clock (slave) but will most likely do it at 50MHz. This is my current interrupt code:



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);
}
}
}


I am still concerned about clock cycles, and I believe I can get away with only checking the DRDY flag if I operate on the presumption that the only other EXTI flag that will trip is for the clock pin. Although I question how this will work if SYS_TICK is running in the background... I'll have to find out.



We're investigating a faster processor to handle the bit-banging, but right now, it looks like the PI3 won't be able to handle it if it's running Linux, and I'm unaware of too many faster processors that run either a very small reliable RTOS, or can be bare metal programmed in a pinch...










share|improve this question
















I'm attempting to create a proper SPI slave interface for an AD7768-4 ADC. The ADC has a SPI interface, but it doesn't output the conversions via SPI. Instead, there are data outputs that are clocked out on individual GPIO pins. So I basically need to bit-bang data, and output to SPI to get a proper slave SPI interface. Please don't ask why I'm doing it this way, it was assigned to me.



The issue I'm having is with the interrupts. I'm using the STM32F767ZI processor - it runs at 216 MHz, and my ADC data MUST BE clocked out at 20MHz. I've set up my NMIs but what I'm not seeing is where the system calls or points to the interrupt handler.



I used the STMCubeMX software to assign pins and generate the setup code, and in the stm32F7xx.c file, it shows the NMI_Handler() function, but I don't see a pointer to it anywhere in the system files. I also found void HAL_GPIO_EXTI_IRQHandler() function in STM32F7xx_hal_gpio.c, which appears to check if the pin is asserted, and clears any pending bits, but it doesn't reset the interrupt flag, or check it, and again, I see no pointer to this function.



To more thoroughly complicate things, I have 10 clock cycles to determine which flag is set (1 of two at a time), reset it, incerment a variable, and move data from the GPIO registers. I believe this is possible, but again, I'm uncertain of what the system is doing as soon as the interrupt is tripped.



Does anyone have any experience in working with external interrupts on this processor that could shed some light on how this particular system handles things? Again - 10 clock cycles to do what I need to... moving data should only take me 1-2 clock cycles, leaving me 8 to handle interrupts...



EDIT:



We changed the DCLK speed to 5.12 MHz (20.48 MHz MCLK/4) because at 2.56 MHz we had exactly 12.5 microseconds to pipe data out and set up for the next DRDY pulse, and 80 kHz speed gives us exactly zero margin. At 5.12 MHz, I have 41 clock cycles to run the interrupt routine, which I can reduce slightly if I skip checking the second flag and just handle incoming data. But I feel I must use the DRDY flag check at least, and use the routine to enable the second interrupt otherwise I'll be constantly interrupting because DCLK on the ADC is always running. This allows me 6.12 microseconds to read in the data, and 6.25 microseconds to shuffle it out before the next DRDY pulse. I should be able to do that at 32 MHz SPI clock (slave) but will most likely do it at 50MHz. This is my current interrupt code:



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);
}
}
}


I am still concerned about clock cycles, and I believe I can get away with only checking the DRDY flag if I operate on the presumption that the only other EXTI flag that will trip is for the clock pin. Although I question how this will work if SYS_TICK is running in the background... I'll have to find out.



We're investigating a faster processor to handle the bit-banging, but right now, it looks like the PI3 won't be able to handle it if it's running Linux, and I'm unaware of too many faster processors that run either a very small reliable RTOS, or can be bare metal programmed in a pinch...







c++ c interrupt stm32f7






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 11:27







Jedi Engineer

















asked Nov 14 '18 at 13:22









Jedi EngineerJedi Engineer

1301721




1301721













  • Consider usage of serial audio interface (SAI) in slave mode with PCM/DSP frames (use ADC DRDY as FS). You can use two SAI channels (2*24 bit slots per channel) if ADC can out samples via DATA0 and DATA1.

    – ReAl
    Nov 14 '18 at 13:46











  • @ReAl - I'm reading DATA),1,2,3 simultaneously. And it's piped in at 20MHz. Not sure SAI can handle that. Thanks though!

    – Jedi Engineer
    Nov 14 '18 at 15:00











  • SAI has two 1-bit channels. One's can connect in parallel frame start (FS) and clock inputs while use data inputs separately, so SAI can receive maximum two data streams from ADC.

    – ReAl
    Nov 14 '18 at 15:25











  • @ReAl, as I indicated before, I have four data inputs to read simultaneously - Data0, Data1, Data2, and Data3. I also have the data clock to follow. It wouldn't work. We explored that already. Thanks Though!

    – Jedi Engineer
    Nov 14 '18 at 15:59











  • @JediEngineer There are 2 SAI controllers with 2 channels each

    – berendi
    Nov 15 '18 at 21:29



















  • Consider usage of serial audio interface (SAI) in slave mode with PCM/DSP frames (use ADC DRDY as FS). You can use two SAI channels (2*24 bit slots per channel) if ADC can out samples via DATA0 and DATA1.

    – ReAl
    Nov 14 '18 at 13:46











  • @ReAl - I'm reading DATA),1,2,3 simultaneously. And it's piped in at 20MHz. Not sure SAI can handle that. Thanks though!

    – Jedi Engineer
    Nov 14 '18 at 15:00











  • SAI has two 1-bit channels. One's can connect in parallel frame start (FS) and clock inputs while use data inputs separately, so SAI can receive maximum two data streams from ADC.

    – ReAl
    Nov 14 '18 at 15:25











  • @ReAl, as I indicated before, I have four data inputs to read simultaneously - Data0, Data1, Data2, and Data3. I also have the data clock to follow. It wouldn't work. We explored that already. Thanks Though!

    – Jedi Engineer
    Nov 14 '18 at 15:59











  • @JediEngineer There are 2 SAI controllers with 2 channels each

    – berendi
    Nov 15 '18 at 21:29

















Consider usage of serial audio interface (SAI) in slave mode with PCM/DSP frames (use ADC DRDY as FS). You can use two SAI channels (2*24 bit slots per channel) if ADC can out samples via DATA0 and DATA1.

– ReAl
Nov 14 '18 at 13:46





Consider usage of serial audio interface (SAI) in slave mode with PCM/DSP frames (use ADC DRDY as FS). You can use two SAI channels (2*24 bit slots per channel) if ADC can out samples via DATA0 and DATA1.

– ReAl
Nov 14 '18 at 13:46













@ReAl - I'm reading DATA),1,2,3 simultaneously. And it's piped in at 20MHz. Not sure SAI can handle that. Thanks though!

– Jedi Engineer
Nov 14 '18 at 15:00





@ReAl - I'm reading DATA),1,2,3 simultaneously. And it's piped in at 20MHz. Not sure SAI can handle that. Thanks though!

– Jedi Engineer
Nov 14 '18 at 15:00













SAI has two 1-bit channels. One's can connect in parallel frame start (FS) and clock inputs while use data inputs separately, so SAI can receive maximum two data streams from ADC.

– ReAl
Nov 14 '18 at 15:25





SAI has two 1-bit channels. One's can connect in parallel frame start (FS) and clock inputs while use data inputs separately, so SAI can receive maximum two data streams from ADC.

– ReAl
Nov 14 '18 at 15:25













@ReAl, as I indicated before, I have four data inputs to read simultaneously - Data0, Data1, Data2, and Data3. I also have the data clock to follow. It wouldn't work. We explored that already. Thanks Though!

– Jedi Engineer
Nov 14 '18 at 15:59





@ReAl, as I indicated before, I have four data inputs to read simultaneously - Data0, Data1, Data2, and Data3. I also have the data clock to follow. It wouldn't work. We explored that already. Thanks Though!

– Jedi Engineer
Nov 14 '18 at 15:59













@JediEngineer There are 2 SAI controllers with 2 channels each

– berendi
Nov 15 '18 at 21:29





@JediEngineer There are 2 SAI controllers with 2 channels each

– berendi
Nov 15 '18 at 21:29












3 Answers
3






active

oldest

votes


















3















10 clock cycles to do what I need to... moving data should only take me 1-2 clock cycles, leaving me 8 to handle interrupts...




No way. Interrupt entry (pushing registers, fetching the vector and filling the pipeline) takes 10-12 cycles even on a Cortex-M7. Then consider a very simple interrupt handler, just moving the input data bits to a buffer and clearing the interrupt flag:



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


it gets translated to something like this



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


So it's 11 instructions, each taking at least one cycle, after interrupt entry. That's assuming the code, vector table, and the stack are all in the fastest RAM region. I'm not sure whether literal pools work in ITCM at all, using immediate literals would add 3 more cycles. Forget it.



This has to be solved with hardware.



The controller has 6 SPI interfaces, pick 4 of them. Connect DRDY to all four NSS pins, DCLK to all SCK pins, and each DOUT pin to one MISO pin. Now each SPI interface handles a single channel, and can collect up to 32 bits in its internal FIFO.



Then I'd set an interrupt on a rising edge on one of the NSS pins (EXTI still works even if the pin is in alternate function mode), and read all data at once.



EDIT



It turns out that the STM32 SPI requres an inordinate amount of delay between NSS falling and SCK rising, which the AD7768 does not provide, so it will not work.



Sigma-Delta interface



The STM32F767 has a DFSDM peripheral, designed to receive data from external ADCs. It can receive up to 8 channels of serial data with 20 MHz, and it can even do some preprocessing that your application might need.



The problem is that the DFSDM has no DRDY input, I don't exactly know how could the data transfer be synchronized. It might work by asserting the START# singal to reset the communication.



If that doesn't work, then you can try starting the DFSDM channels using a timer and DMA. Connect DRDY to the external trigger of TIM1 or TIM8 (other timers won't work, because they are connected to the slower APB1 bus and the other DMA controller), start it on the rising edge of ETR, and let it generate a DMA request after ~20 ns. Then let the DMA write the value needed to start the channel to the DFSDM channel configuration register. Repeat for the oher three channels.






share|improve this answer


























  • @berebdi - thanks for the input. I just arrived at a similar conclusion a few moments ago (with respect to timing). I was unsure of handling the data with the Nucleo SPI channel - I'm going to set that up as you suggested. That makes sense considering that the output appears to be basically a SPI interface. With respect to that - DRDY rises and falls within the n-1 clock cycle with respect to data - that shouldn't make a difference with the SPI input, right? Furthermore, can 4 SPI channels read in data at once? The ADC clocks out all 4 channels at the same time...

    – Jedi Engineer
    Nov 15 '18 at 17:50













  • @JediEngineer Yes, it could be a problem. Looking at the SPI timing diagram in the STM32F767 datasheet, it needs tsu(NSS)=4*Tpclk NSS setup time, that is about 37 ns @ 108MHz APB2 clock, but on the transmitting side, the delay between DRDY falling and DCLK rising is 0 to 4.5 ns. So it will miss the first bit. But I have another idea...

    – berendi
    Nov 15 '18 at 20:05













  • I looked into the DFSDM - it doesn't look like I can use it without the filters... from what I'm seeing. But I'll keep it on hand as a second option. For the time being, I was able to get a reduction in DCLK speed to 2.5MHz, giving me about 84 clock cycles to extract my data. That should be plenty. I'll be reducing code to increase speed, and maybe we'll work with the DFSDM as well, but it's a start for now.

    – Jedi Engineer
    Nov 16 '18 at 11:29













  • @JediEngineer DFSDM filters can be bypassed, see the description of the DFSDM_FLTxFCR register, and it can be somehow synchronized to EXTI14 or EXTI15, so that's where DRDY should go.

    – berendi
    Nov 16 '18 at 14:23



















0














There's a startup file generated before compile: startup_stm32f767xx.s - which contains all the pointers to functions.



Under the marker g_pfnVectors: is .word NMI_Handler pointing to a function for handling the non-masked interrupts, and two other pointers, .word EXTI0_IRQHandler and .word EXTI1_IRQHandler as vectors to the external interrupt handlers. Further down in the same file, is the following compiler directives:



.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


This was the info I was looking for to be able to control my interrupts with more precision and fewer clock cycles.






share|improve this answer

































    0














    I readed AD7768 DS more carefully and found that it can srnd four channels data to one DOUT pin. So, I talking again about serial audio interface (SAI).



    If you can lower DCLK frequency up to 2.5MHz than you can lower sample with ratio 1:8 (as ratio 2.5 MHz to 20 MHz) irt sample rate at full ADC clock.



    If you route all 4 channels to one output DOUT0 you slow down sample rate just in ratio 1:4.



    AD7768-4 DS



    page 53




    On the AD7768, the interface can be configured to output conversion
    data on one, two, or eight of the DOUTx pins. The DOUTx configuration
    for the AD7768 is selected using the FORMATx pins (see Table 33).




    page 66 table 34: (for AD7768-4)
    page 67 figure 98:




    FORMAT0 = 1 All channels output on the DOUT0 pin, in TDM output. Only DOUT0 is in use.




    You can use SAI with FS = DRDY and four slots, 32 bits/slot






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53301251%2fstm32f767zi-external-interrupt-handling%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      3















      10 clock cycles to do what I need to... moving data should only take me 1-2 clock cycles, leaving me 8 to handle interrupts...




      No way. Interrupt entry (pushing registers, fetching the vector and filling the pipeline) takes 10-12 cycles even on a Cortex-M7. Then consider a very simple interrupt handler, just moving the input data bits to a buffer and clearing the interrupt flag:



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


      it gets translated to something like this



      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


      So it's 11 instructions, each taking at least one cycle, after interrupt entry. That's assuming the code, vector table, and the stack are all in the fastest RAM region. I'm not sure whether literal pools work in ITCM at all, using immediate literals would add 3 more cycles. Forget it.



      This has to be solved with hardware.



      The controller has 6 SPI interfaces, pick 4 of them. Connect DRDY to all four NSS pins, DCLK to all SCK pins, and each DOUT pin to one MISO pin. Now each SPI interface handles a single channel, and can collect up to 32 bits in its internal FIFO.



      Then I'd set an interrupt on a rising edge on one of the NSS pins (EXTI still works even if the pin is in alternate function mode), and read all data at once.



      EDIT



      It turns out that the STM32 SPI requres an inordinate amount of delay between NSS falling and SCK rising, which the AD7768 does not provide, so it will not work.



      Sigma-Delta interface



      The STM32F767 has a DFSDM peripheral, designed to receive data from external ADCs. It can receive up to 8 channels of serial data with 20 MHz, and it can even do some preprocessing that your application might need.



      The problem is that the DFSDM has no DRDY input, I don't exactly know how could the data transfer be synchronized. It might work by asserting the START# singal to reset the communication.



      If that doesn't work, then you can try starting the DFSDM channels using a timer and DMA. Connect DRDY to the external trigger of TIM1 or TIM8 (other timers won't work, because they are connected to the slower APB1 bus and the other DMA controller), start it on the rising edge of ETR, and let it generate a DMA request after ~20 ns. Then let the DMA write the value needed to start the channel to the DFSDM channel configuration register. Repeat for the oher three channels.






      share|improve this answer


























      • @berebdi - thanks for the input. I just arrived at a similar conclusion a few moments ago (with respect to timing). I was unsure of handling the data with the Nucleo SPI channel - I'm going to set that up as you suggested. That makes sense considering that the output appears to be basically a SPI interface. With respect to that - DRDY rises and falls within the n-1 clock cycle with respect to data - that shouldn't make a difference with the SPI input, right? Furthermore, can 4 SPI channels read in data at once? The ADC clocks out all 4 channels at the same time...

        – Jedi Engineer
        Nov 15 '18 at 17:50













      • @JediEngineer Yes, it could be a problem. Looking at the SPI timing diagram in the STM32F767 datasheet, it needs tsu(NSS)=4*Tpclk NSS setup time, that is about 37 ns @ 108MHz APB2 clock, but on the transmitting side, the delay between DRDY falling and DCLK rising is 0 to 4.5 ns. So it will miss the first bit. But I have another idea...

        – berendi
        Nov 15 '18 at 20:05













      • I looked into the DFSDM - it doesn't look like I can use it without the filters... from what I'm seeing. But I'll keep it on hand as a second option. For the time being, I was able to get a reduction in DCLK speed to 2.5MHz, giving me about 84 clock cycles to extract my data. That should be plenty. I'll be reducing code to increase speed, and maybe we'll work with the DFSDM as well, but it's a start for now.

        – Jedi Engineer
        Nov 16 '18 at 11:29













      • @JediEngineer DFSDM filters can be bypassed, see the description of the DFSDM_FLTxFCR register, and it can be somehow synchronized to EXTI14 or EXTI15, so that's where DRDY should go.

        – berendi
        Nov 16 '18 at 14:23
















      3















      10 clock cycles to do what I need to... moving data should only take me 1-2 clock cycles, leaving me 8 to handle interrupts...




      No way. Interrupt entry (pushing registers, fetching the vector and filling the pipeline) takes 10-12 cycles even on a Cortex-M7. Then consider a very simple interrupt handler, just moving the input data bits to a buffer and clearing the interrupt flag:



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


      it gets translated to something like this



      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


      So it's 11 instructions, each taking at least one cycle, after interrupt entry. That's assuming the code, vector table, and the stack are all in the fastest RAM region. I'm not sure whether literal pools work in ITCM at all, using immediate literals would add 3 more cycles. Forget it.



      This has to be solved with hardware.



      The controller has 6 SPI interfaces, pick 4 of them. Connect DRDY to all four NSS pins, DCLK to all SCK pins, and each DOUT pin to one MISO pin. Now each SPI interface handles a single channel, and can collect up to 32 bits in its internal FIFO.



      Then I'd set an interrupt on a rising edge on one of the NSS pins (EXTI still works even if the pin is in alternate function mode), and read all data at once.



      EDIT



      It turns out that the STM32 SPI requres an inordinate amount of delay between NSS falling and SCK rising, which the AD7768 does not provide, so it will not work.



      Sigma-Delta interface



      The STM32F767 has a DFSDM peripheral, designed to receive data from external ADCs. It can receive up to 8 channels of serial data with 20 MHz, and it can even do some preprocessing that your application might need.



      The problem is that the DFSDM has no DRDY input, I don't exactly know how could the data transfer be synchronized. It might work by asserting the START# singal to reset the communication.



      If that doesn't work, then you can try starting the DFSDM channels using a timer and DMA. Connect DRDY to the external trigger of TIM1 or TIM8 (other timers won't work, because they are connected to the slower APB1 bus and the other DMA controller), start it on the rising edge of ETR, and let it generate a DMA request after ~20 ns. Then let the DMA write the value needed to start the channel to the DFSDM channel configuration register. Repeat for the oher three channels.






      share|improve this answer


























      • @berebdi - thanks for the input. I just arrived at a similar conclusion a few moments ago (with respect to timing). I was unsure of handling the data with the Nucleo SPI channel - I'm going to set that up as you suggested. That makes sense considering that the output appears to be basically a SPI interface. With respect to that - DRDY rises and falls within the n-1 clock cycle with respect to data - that shouldn't make a difference with the SPI input, right? Furthermore, can 4 SPI channels read in data at once? The ADC clocks out all 4 channels at the same time...

        – Jedi Engineer
        Nov 15 '18 at 17:50













      • @JediEngineer Yes, it could be a problem. Looking at the SPI timing diagram in the STM32F767 datasheet, it needs tsu(NSS)=4*Tpclk NSS setup time, that is about 37 ns @ 108MHz APB2 clock, but on the transmitting side, the delay between DRDY falling and DCLK rising is 0 to 4.5 ns. So it will miss the first bit. But I have another idea...

        – berendi
        Nov 15 '18 at 20:05













      • I looked into the DFSDM - it doesn't look like I can use it without the filters... from what I'm seeing. But I'll keep it on hand as a second option. For the time being, I was able to get a reduction in DCLK speed to 2.5MHz, giving me about 84 clock cycles to extract my data. That should be plenty. I'll be reducing code to increase speed, and maybe we'll work with the DFSDM as well, but it's a start for now.

        – Jedi Engineer
        Nov 16 '18 at 11:29













      • @JediEngineer DFSDM filters can be bypassed, see the description of the DFSDM_FLTxFCR register, and it can be somehow synchronized to EXTI14 or EXTI15, so that's where DRDY should go.

        – berendi
        Nov 16 '18 at 14:23














      3












      3








      3








      10 clock cycles to do what I need to... moving data should only take me 1-2 clock cycles, leaving me 8 to handle interrupts...




      No way. Interrupt entry (pushing registers, fetching the vector and filling the pipeline) takes 10-12 cycles even on a Cortex-M7. Then consider a very simple interrupt handler, just moving the input data bits to a buffer and clearing the interrupt flag:



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


      it gets translated to something like this



      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


      So it's 11 instructions, each taking at least one cycle, after interrupt entry. That's assuming the code, vector table, and the stack are all in the fastest RAM region. I'm not sure whether literal pools work in ITCM at all, using immediate literals would add 3 more cycles. Forget it.



      This has to be solved with hardware.



      The controller has 6 SPI interfaces, pick 4 of them. Connect DRDY to all four NSS pins, DCLK to all SCK pins, and each DOUT pin to one MISO pin. Now each SPI interface handles a single channel, and can collect up to 32 bits in its internal FIFO.



      Then I'd set an interrupt on a rising edge on one of the NSS pins (EXTI still works even if the pin is in alternate function mode), and read all data at once.



      EDIT



      It turns out that the STM32 SPI requres an inordinate amount of delay between NSS falling and SCK rising, which the AD7768 does not provide, so it will not work.



      Sigma-Delta interface



      The STM32F767 has a DFSDM peripheral, designed to receive data from external ADCs. It can receive up to 8 channels of serial data with 20 MHz, and it can even do some preprocessing that your application might need.



      The problem is that the DFSDM has no DRDY input, I don't exactly know how could the data transfer be synchronized. It might work by asserting the START# singal to reset the communication.



      If that doesn't work, then you can try starting the DFSDM channels using a timer and DMA. Connect DRDY to the external trigger of TIM1 or TIM8 (other timers won't work, because they are connected to the slower APB1 bus and the other DMA controller), start it on the rising edge of ETR, and let it generate a DMA request after ~20 ns. Then let the DMA write the value needed to start the channel to the DFSDM channel configuration register. Repeat for the oher three channels.






      share|improve this answer
















      10 clock cycles to do what I need to... moving data should only take me 1-2 clock cycles, leaving me 8 to handle interrupts...




      No way. Interrupt entry (pushing registers, fetching the vector and filling the pipeline) takes 10-12 cycles even on a Cortex-M7. Then consider a very simple interrupt handler, just moving the input data bits to a buffer and clearing the interrupt flag:



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


      it gets translated to something like this



      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


      So it's 11 instructions, each taking at least one cycle, after interrupt entry. That's assuming the code, vector table, and the stack are all in the fastest RAM region. I'm not sure whether literal pools work in ITCM at all, using immediate literals would add 3 more cycles. Forget it.



      This has to be solved with hardware.



      The controller has 6 SPI interfaces, pick 4 of them. Connect DRDY to all four NSS pins, DCLK to all SCK pins, and each DOUT pin to one MISO pin. Now each SPI interface handles a single channel, and can collect up to 32 bits in its internal FIFO.



      Then I'd set an interrupt on a rising edge on one of the NSS pins (EXTI still works even if the pin is in alternate function mode), and read all data at once.



      EDIT



      It turns out that the STM32 SPI requres an inordinate amount of delay between NSS falling and SCK rising, which the AD7768 does not provide, so it will not work.



      Sigma-Delta interface



      The STM32F767 has a DFSDM peripheral, designed to receive data from external ADCs. It can receive up to 8 channels of serial data with 20 MHz, and it can even do some preprocessing that your application might need.



      The problem is that the DFSDM has no DRDY input, I don't exactly know how could the data transfer be synchronized. It might work by asserting the START# singal to reset the communication.



      If that doesn't work, then you can try starting the DFSDM channels using a timer and DMA. Connect DRDY to the external trigger of TIM1 or TIM8 (other timers won't work, because they are connected to the slower APB1 bus and the other DMA controller), start it on the rising edge of ETR, and let it generate a DMA request after ~20 ns. Then let the DMA write the value needed to start the channel to the DFSDM channel configuration register. Repeat for the oher three channels.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 15 '18 at 21:40

























      answered Nov 14 '18 at 21:59









      berendiberendi

      3,9601624




      3,9601624













      • @berebdi - thanks for the input. I just arrived at a similar conclusion a few moments ago (with respect to timing). I was unsure of handling the data with the Nucleo SPI channel - I'm going to set that up as you suggested. That makes sense considering that the output appears to be basically a SPI interface. With respect to that - DRDY rises and falls within the n-1 clock cycle with respect to data - that shouldn't make a difference with the SPI input, right? Furthermore, can 4 SPI channels read in data at once? The ADC clocks out all 4 channels at the same time...

        – Jedi Engineer
        Nov 15 '18 at 17:50













      • @JediEngineer Yes, it could be a problem. Looking at the SPI timing diagram in the STM32F767 datasheet, it needs tsu(NSS)=4*Tpclk NSS setup time, that is about 37 ns @ 108MHz APB2 clock, but on the transmitting side, the delay between DRDY falling and DCLK rising is 0 to 4.5 ns. So it will miss the first bit. But I have another idea...

        – berendi
        Nov 15 '18 at 20:05













      • I looked into the DFSDM - it doesn't look like I can use it without the filters... from what I'm seeing. But I'll keep it on hand as a second option. For the time being, I was able to get a reduction in DCLK speed to 2.5MHz, giving me about 84 clock cycles to extract my data. That should be plenty. I'll be reducing code to increase speed, and maybe we'll work with the DFSDM as well, but it's a start for now.

        – Jedi Engineer
        Nov 16 '18 at 11:29













      • @JediEngineer DFSDM filters can be bypassed, see the description of the DFSDM_FLTxFCR register, and it can be somehow synchronized to EXTI14 or EXTI15, so that's where DRDY should go.

        – berendi
        Nov 16 '18 at 14:23



















      • @berebdi - thanks for the input. I just arrived at a similar conclusion a few moments ago (with respect to timing). I was unsure of handling the data with the Nucleo SPI channel - I'm going to set that up as you suggested. That makes sense considering that the output appears to be basically a SPI interface. With respect to that - DRDY rises and falls within the n-1 clock cycle with respect to data - that shouldn't make a difference with the SPI input, right? Furthermore, can 4 SPI channels read in data at once? The ADC clocks out all 4 channels at the same time...

        – Jedi Engineer
        Nov 15 '18 at 17:50













      • @JediEngineer Yes, it could be a problem. Looking at the SPI timing diagram in the STM32F767 datasheet, it needs tsu(NSS)=4*Tpclk NSS setup time, that is about 37 ns @ 108MHz APB2 clock, but on the transmitting side, the delay between DRDY falling and DCLK rising is 0 to 4.5 ns. So it will miss the first bit. But I have another idea...

        – berendi
        Nov 15 '18 at 20:05













      • I looked into the DFSDM - it doesn't look like I can use it without the filters... from what I'm seeing. But I'll keep it on hand as a second option. For the time being, I was able to get a reduction in DCLK speed to 2.5MHz, giving me about 84 clock cycles to extract my data. That should be plenty. I'll be reducing code to increase speed, and maybe we'll work with the DFSDM as well, but it's a start for now.

        – Jedi Engineer
        Nov 16 '18 at 11:29













      • @JediEngineer DFSDM filters can be bypassed, see the description of the DFSDM_FLTxFCR register, and it can be somehow synchronized to EXTI14 or EXTI15, so that's where DRDY should go.

        – berendi
        Nov 16 '18 at 14:23

















      @berebdi - thanks for the input. I just arrived at a similar conclusion a few moments ago (with respect to timing). I was unsure of handling the data with the Nucleo SPI channel - I'm going to set that up as you suggested. That makes sense considering that the output appears to be basically a SPI interface. With respect to that - DRDY rises and falls within the n-1 clock cycle with respect to data - that shouldn't make a difference with the SPI input, right? Furthermore, can 4 SPI channels read in data at once? The ADC clocks out all 4 channels at the same time...

      – Jedi Engineer
      Nov 15 '18 at 17:50







      @berebdi - thanks for the input. I just arrived at a similar conclusion a few moments ago (with respect to timing). I was unsure of handling the data with the Nucleo SPI channel - I'm going to set that up as you suggested. That makes sense considering that the output appears to be basically a SPI interface. With respect to that - DRDY rises and falls within the n-1 clock cycle with respect to data - that shouldn't make a difference with the SPI input, right? Furthermore, can 4 SPI channels read in data at once? The ADC clocks out all 4 channels at the same time...

      – Jedi Engineer
      Nov 15 '18 at 17:50















      @JediEngineer Yes, it could be a problem. Looking at the SPI timing diagram in the STM32F767 datasheet, it needs tsu(NSS)=4*Tpclk NSS setup time, that is about 37 ns @ 108MHz APB2 clock, but on the transmitting side, the delay between DRDY falling and DCLK rising is 0 to 4.5 ns. So it will miss the first bit. But I have another idea...

      – berendi
      Nov 15 '18 at 20:05







      @JediEngineer Yes, it could be a problem. Looking at the SPI timing diagram in the STM32F767 datasheet, it needs tsu(NSS)=4*Tpclk NSS setup time, that is about 37 ns @ 108MHz APB2 clock, but on the transmitting side, the delay between DRDY falling and DCLK rising is 0 to 4.5 ns. So it will miss the first bit. But I have another idea...

      – berendi
      Nov 15 '18 at 20:05















      I looked into the DFSDM - it doesn't look like I can use it without the filters... from what I'm seeing. But I'll keep it on hand as a second option. For the time being, I was able to get a reduction in DCLK speed to 2.5MHz, giving me about 84 clock cycles to extract my data. That should be plenty. I'll be reducing code to increase speed, and maybe we'll work with the DFSDM as well, but it's a start for now.

      – Jedi Engineer
      Nov 16 '18 at 11:29







      I looked into the DFSDM - it doesn't look like I can use it without the filters... from what I'm seeing. But I'll keep it on hand as a second option. For the time being, I was able to get a reduction in DCLK speed to 2.5MHz, giving me about 84 clock cycles to extract my data. That should be plenty. I'll be reducing code to increase speed, and maybe we'll work with the DFSDM as well, but it's a start for now.

      – Jedi Engineer
      Nov 16 '18 at 11:29















      @JediEngineer DFSDM filters can be bypassed, see the description of the DFSDM_FLTxFCR register, and it can be somehow synchronized to EXTI14 or EXTI15, so that's where DRDY should go.

      – berendi
      Nov 16 '18 at 14:23





      @JediEngineer DFSDM filters can be bypassed, see the description of the DFSDM_FLTxFCR register, and it can be somehow synchronized to EXTI14 or EXTI15, so that's where DRDY should go.

      – berendi
      Nov 16 '18 at 14:23













      0














      There's a startup file generated before compile: startup_stm32f767xx.s - which contains all the pointers to functions.



      Under the marker g_pfnVectors: is .word NMI_Handler pointing to a function for handling the non-masked interrupts, and two other pointers, .word EXTI0_IRQHandler and .word EXTI1_IRQHandler as vectors to the external interrupt handlers. Further down in the same file, is the following compiler directives:



      .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


      This was the info I was looking for to be able to control my interrupts with more precision and fewer clock cycles.






      share|improve this answer






























        0














        There's a startup file generated before compile: startup_stm32f767xx.s - which contains all the pointers to functions.



        Under the marker g_pfnVectors: is .word NMI_Handler pointing to a function for handling the non-masked interrupts, and two other pointers, .word EXTI0_IRQHandler and .word EXTI1_IRQHandler as vectors to the external interrupt handlers. Further down in the same file, is the following compiler directives:



        .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


        This was the info I was looking for to be able to control my interrupts with more precision and fewer clock cycles.






        share|improve this answer




























          0












          0








          0







          There's a startup file generated before compile: startup_stm32f767xx.s - which contains all the pointers to functions.



          Under the marker g_pfnVectors: is .word NMI_Handler pointing to a function for handling the non-masked interrupts, and two other pointers, .word EXTI0_IRQHandler and .word EXTI1_IRQHandler as vectors to the external interrupt handlers. Further down in the same file, is the following compiler directives:



          .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


          This was the info I was looking for to be able to control my interrupts with more precision and fewer clock cycles.






          share|improve this answer















          There's a startup file generated before compile: startup_stm32f767xx.s - which contains all the pointers to functions.



          Under the marker g_pfnVectors: is .word NMI_Handler pointing to a function for handling the non-masked interrupts, and two other pointers, .word EXTI0_IRQHandler and .word EXTI1_IRQHandler as vectors to the external interrupt handlers. Further down in the same file, is the following compiler directives:



          .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


          This was the info I was looking for to be able to control my interrupts with more precision and fewer clock cycles.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 14 '18 at 22:02









          Jonathon Reinhart

          90.9k20164232




          90.9k20164232










          answered Nov 14 '18 at 15:57









          Jedi EngineerJedi Engineer

          1301721




          1301721























              0














              I readed AD7768 DS more carefully and found that it can srnd four channels data to one DOUT pin. So, I talking again about serial audio interface (SAI).



              If you can lower DCLK frequency up to 2.5MHz than you can lower sample with ratio 1:8 (as ratio 2.5 MHz to 20 MHz) irt sample rate at full ADC clock.



              If you route all 4 channels to one output DOUT0 you slow down sample rate just in ratio 1:4.



              AD7768-4 DS



              page 53




              On the AD7768, the interface can be configured to output conversion
              data on one, two, or eight of the DOUTx pins. The DOUTx configuration
              for the AD7768 is selected using the FORMATx pins (see Table 33).




              page 66 table 34: (for AD7768-4)
              page 67 figure 98:




              FORMAT0 = 1 All channels output on the DOUT0 pin, in TDM output. Only DOUT0 is in use.




              You can use SAI with FS = DRDY and four slots, 32 bits/slot






              share|improve this answer




























                0














                I readed AD7768 DS more carefully and found that it can srnd four channels data to one DOUT pin. So, I talking again about serial audio interface (SAI).



                If you can lower DCLK frequency up to 2.5MHz than you can lower sample with ratio 1:8 (as ratio 2.5 MHz to 20 MHz) irt sample rate at full ADC clock.



                If you route all 4 channels to one output DOUT0 you slow down sample rate just in ratio 1:4.



                AD7768-4 DS



                page 53




                On the AD7768, the interface can be configured to output conversion
                data on one, two, or eight of the DOUTx pins. The DOUTx configuration
                for the AD7768 is selected using the FORMATx pins (see Table 33).




                page 66 table 34: (for AD7768-4)
                page 67 figure 98:




                FORMAT0 = 1 All channels output on the DOUT0 pin, in TDM output. Only DOUT0 is in use.




                You can use SAI with FS = DRDY and four slots, 32 bits/slot






                share|improve this answer


























                  0












                  0








                  0







                  I readed AD7768 DS more carefully and found that it can srnd four channels data to one DOUT pin. So, I talking again about serial audio interface (SAI).



                  If you can lower DCLK frequency up to 2.5MHz than you can lower sample with ratio 1:8 (as ratio 2.5 MHz to 20 MHz) irt sample rate at full ADC clock.



                  If you route all 4 channels to one output DOUT0 you slow down sample rate just in ratio 1:4.



                  AD7768-4 DS



                  page 53




                  On the AD7768, the interface can be configured to output conversion
                  data on one, two, or eight of the DOUTx pins. The DOUTx configuration
                  for the AD7768 is selected using the FORMATx pins (see Table 33).




                  page 66 table 34: (for AD7768-4)
                  page 67 figure 98:




                  FORMAT0 = 1 All channels output on the DOUT0 pin, in TDM output. Only DOUT0 is in use.




                  You can use SAI with FS = DRDY and four slots, 32 bits/slot






                  share|improve this answer













                  I readed AD7768 DS more carefully and found that it can srnd four channels data to one DOUT pin. So, I talking again about serial audio interface (SAI).



                  If you can lower DCLK frequency up to 2.5MHz than you can lower sample with ratio 1:8 (as ratio 2.5 MHz to 20 MHz) irt sample rate at full ADC clock.



                  If you route all 4 channels to one output DOUT0 you slow down sample rate just in ratio 1:4.



                  AD7768-4 DS



                  page 53




                  On the AD7768, the interface can be configured to output conversion
                  data on one, two, or eight of the DOUTx pins. The DOUTx configuration
                  for the AD7768 is selected using the FORMATx pins (see Table 33).




                  page 66 table 34: (for AD7768-4)
                  page 67 figure 98:




                  FORMAT0 = 1 All channels output on the DOUT0 pin, in TDM output. Only DOUT0 is in use.




                  You can use SAI with FS = DRDY and four slots, 32 bits/slot







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 16 '18 at 20:27









                  ReAlReAl

                  7161216




                  7161216






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53301251%2fstm32f767zi-external-interrupt-handling%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Florida Star v. B. J. F.

                      Error while running script in elastic search , gateway timeout

                      Adding quotations to stringified JSON object values