Hi everyone,
I'm seeing some unwanted behavior and I was hoping that someone could advice on what it could be caused by and/or what could I do about it.
Long story short, I'm working on reading some parallel data stream from a CMOS sensor. For testing purposed, instead of the actual sensor, I've hooked up Teensy 4.1 to a signal generator in a following way
- pins 10, 12, 11, 13, 8, 7, 36, 37, 6, 9, 35, 34 receive the parallel data - right now it's just a binary counter, clocked anywhere up to 50MHz
- pin 32 gets the corresponding clock signal
- pin 4 gets the DATA VALID signal - which is low when the input data should be ignored and high when it should be processed.
It generally works, with one small caviat: sometime, the DATA VALID line gets high even though I'm outputting low from the signal generator.
I initially though that it's a problem with the setup of the readout (the docs are pretty convoluted, it's easy to miss something like that), but I managed to simplify the entire setup, where I dont do any readout, I ignore the data completely, I only look for edges in the DATA VALID signal, using XBAR's edge detection combined with some interrupts. The bare-bones test code looks like this:
It hooks up the DATA_VALID line to the XBAR, connects it to the 0th output and sets up edge detection on it, triggering interrupt on each. The handler only increments a variable, so I can see how many times it fired. And with the above code, and all that clocking hooked up to the remaining pins as described above, I'm seeing multiple edges even though the DATA_VALID is (supposedly) low all the time.
The number of the detected edges highly depends on the clocking of the data signal, I start seeing them around 100kHz, and when I go to 50MHz, it can pick up over 2000 random edges per 100ms. The numbers change when I *touch* other pins on Teensy. And it doesn't happen until the bus is wide enough - when I limit the number of parallel lines to 8, I'm not seeing any of this even when the signal is clocked at 50MHz.
All that makes me think that's some problem with signal integrity, and in fact there are some spikes in the DATA_VALID signal that cause the microcontroller to interpret them at HIGHs. I tried probing the DATA VALID at the connected pin, but it looks relatively fine on the oscilloscope - sure, there's noise there, but it doesn't go over 200mV-300mV max. I tried hooking the DATA_VALID line through the XBAR to another pin and investigating it there, but it looks similar too. That said, I'm only using Analog Discovery 2 for both signal generation and investigation, its bandwidth is pretty low, something like 30Mhz, so maybe these spikes are simply missed. And all this signal is hooked up through these regular hookup wires - so I'm not really sure how much they affect the signal integrity. I tried messing with the hysteresis setting on that DATA VALID pin, but it doesn't really help - it does however change the numbers of the ticks recorded (whatever that indicates...)
Have anyone seen similar behavior? Is this normal? What can/should I do to remedy it? I don't have much experience in circuit design, so it's quite possible that it's one of these "oh yeah, you need to do XXXX", and I would be really grateful if someone could point me in some right direction.
I'm seeing some unwanted behavior and I was hoping that someone could advice on what it could be caused by and/or what could I do about it.
Long story short, I'm working on reading some parallel data stream from a CMOS sensor. For testing purposed, instead of the actual sensor, I've hooked up Teensy 4.1 to a signal generator in a following way
- pins 10, 12, 11, 13, 8, 7, 36, 37, 6, 9, 35, 34 receive the parallel data - right now it's just a binary counter, clocked anywhere up to 50MHz
- pin 32 gets the corresponding clock signal
- pin 4 gets the DATA VALID signal - which is low when the input data should be ignored and high when it should be processed.
It generally works, with one small caviat: sometime, the DATA VALID line gets high even though I'm outputting low from the signal generator.
I initially though that it's a problem with the setup of the readout (the docs are pretty convoluted, it's easy to miss something like that), but I managed to simplify the entire setup, where I dont do any readout, I ignore the data completely, I only look for edges in the DATA VALID signal, using XBAR's edge detection combined with some interrupts. The bare-bones test code looks like this:
Code:
uint32_t numXbarInterrupts;
uint32_t lastSeenXbarInterrupt;
void xbar_connect(unsigned int input, unsigned int output)
{
if (input >= 88) return;
if (output >= 132) return;
volatile uint16_t *xbar = &XBARA1_SEL0 + (output / 2);
uint16_t val = *xbar;
if (!(output & 1)) {
val = (val & 0xFF00) | input;
} else {
val = (val & 0x00FF) | (input << 8);
}
*xbar = val;
}
void xbarInterrupt()
{
XBARA1_CTRL0 |= XBARA_CTRL_STS0;
asm("DSB");
++numXbarInterrupts;
}
void setup()
{
Serial.begin(115200);
// enable clock for clock XBAR
CCM_CCGR2 |= CCM_CCGR2_XBAR1(CCM_CCGR_ON);
// set the IOMUX mode to 3, to route it to XBAR
IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_06 = 3;
//IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_06 = IOMUXC_PAD_HYS | IOMUXC_PAD_PUS( 0 ) | IOMUXC_PAD_SPEED( 11 );
// set XBAR1_IO008 to INPUT
IOMUXC_GPR_GPR6 &= ~(IOMUXC_GPR_GPR6_IOMUXC_XBAR_DIR_SEL_8);
// daisy chaining - select between EMC06 and SD_B0_04
IOMUXC_XBAR1_IN08_SELECT_INPUT = 0;
// detect edges, trigger interrupts
XBARA1_CTRL0 = XBARA_CTRL_STS0 | XBARA_CTRL_EDGE0(3) | XBARA_CTRL_IEN0;
// connect the interrupt to the trigger pad to see if it sees these extra transitions
xbar_connect( XBARA1_IN_IOMUX_XBAR_INOUT08, XBARA1_OUT_DMA_CH_MUX_REQ30 );
attachInterruptVector( IRQ_XBAR1_01, xbarInterrupt );
NVIC_ENABLE_IRQ( IRQ_XBAR1_01 );
}
void loop()
{
delay( 100 );
if ( lastSeenXbarInterrupt != numXbarInterrupts )
{
Serial.printf( "Num interrupts %d\n", numXbarInterrupts - lastSeenXbarInterrupt );
lastSeenXbarInterrupt = numXbarInterrupts;
}
else
{
//Serial.printf("Nothing\n" );
}
}
It hooks up the DATA_VALID line to the XBAR, connects it to the 0th output and sets up edge detection on it, triggering interrupt on each. The handler only increments a variable, so I can see how many times it fired. And with the above code, and all that clocking hooked up to the remaining pins as described above, I'm seeing multiple edges even though the DATA_VALID is (supposedly) low all the time.
The number of the detected edges highly depends on the clocking of the data signal, I start seeing them around 100kHz, and when I go to 50MHz, it can pick up over 2000 random edges per 100ms. The numbers change when I *touch* other pins on Teensy. And it doesn't happen until the bus is wide enough - when I limit the number of parallel lines to 8, I'm not seeing any of this even when the signal is clocked at 50MHz.
All that makes me think that's some problem with signal integrity, and in fact there are some spikes in the DATA_VALID signal that cause the microcontroller to interpret them at HIGHs. I tried probing the DATA VALID at the connected pin, but it looks relatively fine on the oscilloscope - sure, there's noise there, but it doesn't go over 200mV-300mV max. I tried hooking the DATA_VALID line through the XBAR to another pin and investigating it there, but it looks similar too. That said, I'm only using Analog Discovery 2 for both signal generation and investigation, its bandwidth is pretty low, something like 30Mhz, so maybe these spikes are simply missed. And all this signal is hooked up through these regular hookup wires - so I'm not really sure how much they affect the signal integrity. I tried messing with the hysteresis setting on that DATA VALID pin, but it doesn't really help - it does however change the numbers of the ticks recorded (whatever that indicates...)
Have anyone seen similar behavior? Is this normal? What can/should I do to remedy it? I don't have much experience in circuit design, so it's quite possible that it's one of these "oh yeah, you need to do XXXX", and I would be really grateful if someone could point me in some right direction.