DroneOverLord
Active member
I have a project reading a 320x356 16bit image from a FLIR Boson Camera. It uses a standard CSI type interface (V Sync, H Sync, Pixel Clock and Data Valid) but for the life of me I can't seem to figure out how to get good data out of the camera with a Teensy 4.1.
I designed a board to interface with it and the camera is functional by hooking it up via USB.
I've also scooped all the pins and the signals are clean. V Sync is running at 60Hz and is detected without any issues with correct timing. Now Data Valid is running at 15.7Khz, and the signal is clean but there seems to be an issue with the pin...it should only be triggered 320 times a second but it's being triggered 1k-3k times a second....
Looking at the data sheet the Teensy 4.1 should be able to handle a transition rate of 1.06ns in fast mode...I can't figure out how to see if that's the default mode for the Teensy.
The Pixel Clock runs at 27Mhz, I'm reading the port directly to read the 16 parrel bits so I should be able to read them fast enough right?
I designed a board to interface with it and the camera is functional by hooking it up via USB.
I've also scooped all the pins and the signals are clean. V Sync is running at 60Hz and is detected without any issues with correct timing. Now Data Valid is running at 15.7Khz, and the signal is clean but there seems to be an issue with the pin...it should only be triggered 320 times a second but it's being triggered 1k-3k times a second....
Looking at the data sheet the Teensy 4.1 should be able to handle a transition rate of 1.06ns in fast mode...I can't figure out how to see if that's the default mode for the Teensy.
The Pixel Clock runs at 27Mhz, I'm reading the port directly to read the 16 parrel bits so I should be able to read them fast enough right?
Code:
/*
June 2022
Don Yates
This Driver takes a raw 16bit image from the BOSON
FLIR camera and stores it on an SD card
*/
#include <avr/io.h>
#include <avr/interrupt.h>
//Defining PINS
const int LED = 13;
#define D0 19 //GPIO_AD_B1_00
#define D1 18 //GPIO_AD_B1_01
#define D2 14 //GPIO_AD_B1_02
#define D3 15 //GPIO_AD_B1_03
#define D4 40 //GPIO_AD_B1_04
#define D5 41 //GPIO_AD_B1_05
#define D6 17 //GPIO_AD_B1_06
#define D7 16 //GPIO_AD_B1_07
#define D8 22 //GPIO_AD_B1_08
#define D9 23 //GPIO_AD_B1_09
#define D10 20 //GPIO_AD_B1_10
#define D11 21 //GPIO_AD_B1_11
#define D12 38 //GPIO_AD_B1_12
#define D13 39 //GPIO_AD_B1_13
#define D14 26 //GPIO_AD_B1_14
#define D15 27 //GPIO_AD_B1_15
#define PIXCLK 32
#define V_SYNC 6
#define H_SYNC 2
#define DATA_VALID 9
#define LEDON digitalWriteFast(LED, HIGH);
#define LEDOFF digitalWriteFast(LED, LOW);
/**************************** Setup ***************************/
void setup() {
//initialize the digital pin as an output.
pinMode(LED, OUTPUT);
pinMode(D0, INPUT);
pinMode(D1, INPUT);
pinMode(D2, INPUT);
pinMode(D3, INPUT);
pinMode(D4, INPUT);
pinMode(D5, INPUT);
pinMode(D6, INPUT);
pinMode(D7, INPUT);
pinMode(D8, INPUT);
pinMode(D9, INPUT);
pinMode(D10, INPUT);
pinMode(D11, INPUT);
pinMode(D12, INPUT);
pinMode(D13, INPUT);
pinMode(D14, INPUT);
pinMode(D15, INPUT);
pinMode(PIXCLK, INPUT);
pinMode(V_SYNC, INPUT);
//pinMode(V_SYNC, INPUT_PULLUP);
pinMode(H_SYNC, INPUT);
pinMode(DATA_VALID, INPUT);
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
;// wait for serial port to connect. Needed for native USB port only
}
//Setup Interrupts
// attachInterrupt(digitalPinToInterrupt(V_SYNC), ISR_V_SYNC, FALLING);
}/************************************************************************/
//*** Global Variables ***
//Camera Resolution 320/256
uint16_t g_Frame[320 * 256];
static int g_FrameWidth() { return 320; }
static int g_FrameHeight() { return 256; }
unsigned int g_FrameIndex=0;
int g_FrameRate = 1;
volatile unsigned int g_Count=0;
unsigned int LowLastTime = 0;
unsigned int LowLastTwoTime = 0;
unsigned int LoopCount = 0;
// Global timing variables
volatile uint32_t g_subcnt, g_subcnt_start, g_subcnt_end;
volatile uint32_t g_cnt, g_cnt_start, g_cnt_end;
volatile unsigned int g_ISR_Triggered = 0;
float g_ns;
/*************************************************************************/
/* Main Loop */
/*************************************************************************/
void loop() {
uint16_t Frames = 0;
uint16_t Rows = 0;
uint16_t Pixels = 0;
int temp;
while(1){
//Check if V_SYNC is low and transitions to high
if(!digitalReadFast(V_SYNC)){//If Sync Low
g_FrameIndex = 0;// Reset the Frame Index
/********************* Getting Frame ***************************/
while(!digitalReadFast(V_SYNC)){ //Wait till Sync goes high, START OF NEW FRAME
delayNanoseconds(1);
}
g_cnt_start = ARM_DWT_CYCCNT;//Get current processor clock cycle number
Frames++;//New Frame on Rising V_Sync
Rows = 0;
Pixels = 0;
/********************* Getting Row ***************************/
while(digitalReadFast(V_SYNC)){
Rows++; //Rising Data Valid means new Row
//temp = digitalReadFast(DATA_VALID);
while(digitalReadFast(DATA_VALID)){
if(digitalReadFast(PIXCLK)){
Pixels++;
//g_subcnt_start = ARM_DWT_CYCCNT; //Get current processor clock cycle number
g_Frame[g_FrameIndex++] = cameraReadPixels();
//g_subcnt_end = ARM_DWT_CYCCNT; //Get current processor clock cycle number
}
else{
delayNanoseconds(1);
}
}
}
}
if(Frames >=60){
g_cnt_end = ARM_DWT_CYCCNT;//Get new processor clock cycle number
Serial.print("Number of Frames = ");
Serial.println(Frames);
Serial.print("Number of Rows = ");
Serial.println(Rows);
Serial.print("Number of Pixels = ");
Serial.println(Pixels);
g_FrameIndex = 0;
Frames = 0;
Rows = 0;
Pixels = 0;
//g_cnt = g_subcnt_end - g_subcnt_start;
//g_ns = g_cnt*1E9f/F_CPU;
//Serial.printf("Subroutine time: %5u (%0.6g ns)\n",g_cnt, g_ns);
g_cnt = g_cnt_end - g_cnt_start;
g_ns = g_cnt*1E9f/F_CPU;
Serial.printf("Total Run Time: %10u (%0.6g ns)\n",g_cnt, g_ns);
Serial.print("Frame Data: ");
Serial.println(g_Frame[10]);
Serial.println("**************************************");
LEDON;
delay(500); // wait for a second/2
LEDOFF;
delay(500); // wait for a second/2
}
}
}/************************************************************************/
/*************************************************************************/
// Read a uint8_t of the pixel data
static inline uint16_t cameraReadPixels()
{
uint16_t b = 0;
uint32_t pword= GPIO6_DR >> 16; // get the port bits
b = (uint16_t)pword;
return b;
}/************************************************************************/