I2C is used to read the serial number of the camera to check if the camera is working good. I am using the default settings of the camera and SPI reads 16bit registers to get the camera readings. Initially establishing synchronizing is essential.I have done that by calling LeptonSync() function.I Used UMFT234XF Development Module (USB to UART) to send the reading value to Visual Microsoft Studio to process the image.
#include "main.h"
#include "stdbool.h"
#include "stdio.h"
#include <inttypes.h>
#include "stdlib.h"
#include <string.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
int8_t x = 0;
#define ADDRESS (0x2A)
#define AGC (0x01)
#define SYS (0x02)
#define VID (0x03)
#define OEM (0x08)
#define GET (0x00)
#define SET (0x01)
#define RUN (0x02)
#define VOSPI_FRAME_SIZE (164)
#define VOSPI_FRAME_SIZE1 (82)
/* Private variables ---------------------------------------------------------*/
int8_t BufferRX[2];
int8_t BufferRX1[2];
int TxIndex=0;
uint8_t lepton_frame_packet[VOSPI_FRAME_SIZE];
uint16_t lepton_frame_packet1[VOSPI_FRAME_SIZE1];
int16_t wordVal;
bool donecapturing= false;
uint16_t image[80][60];
uint8_t IDarray[60];
int ID[60];
int k=0;
int t=0;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config1(void);
void I2C_Init(void);
void CLK_Init(void);
void FLepton_I2C_Read(void);
void SPI_Init(void);
void Timer_Clock_Init(void);
void Delay(int);
void LeptonSync(void);
void Read_lepton_frame(void);
void USART_Init(void);
void Print_lepton_frame(void);
void Print_Image(void);
void Print_BitVal(int16_t);
void Buffer_Image(void);
volatile uint8_t Val_3;
void send_InitBits(void);
/* Private functions ---------------------------------------------------------*/
int main(void)
{
SystemClock_Config1();
//I2C------------
CLK_Init();
LL_I2C_Disable(I2C1);
I2C_Init();
LL_I2C_Enable(I2C1);
FLepton_I2C_Read();
//------------------
//SPI1--------------
SPI_Init();
Timer_Clock_Init();
LL_SPI_Enable(SPI1);
//spi CLK
GPIOA->ODR &= ~LL_GPIO_PIN_5;
//---------------------
//USART-----------------
USART_Init();
LL_USART_Enable(USART2);
//---------------------------
while(1){
LeptonSync();
Delay(50);
while (donecapturing == false)
{
Read_lepton_frame();
Buffer_Image();
}
donecapturing = false;
send_InitBits();
Print_Image();
Delay(999);
Delay(999);
Delay(999);
}
}
void CLK_Init(){
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOF);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
}
void I2C_Init(){
LL_I2C_InitTypeDef I2C_InitStruct;
LL_GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = LL_GPIO_PIN_8;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/**I2C Initialization */
I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
I2C_InitStruct.Timing = 0x00000E14;
I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
I2C_InitStruct.DigitalFilter = 0;
I2C_InitStruct.OwnAddress1 = 0;
I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
LL_I2C_Init(I2C1, &I2C_InitStruct);
LL_I2C_EnableAutoEndMode(I2C1);
LL_I2C_DisableOwnAddress2(I2C1);
LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_SYSCLK);
LL_I2C_DisableGeneralCall(I2C1);
LL_I2C_EnableClockStretching(I2C1);
}
void FLepton_I2C_Read()
{
uint8_t TxBuffer[] = {0x00,0x04,0x02,0x08}; //sending command reg addr and get serial address
uint8_t TxBuffer1[] = {0x00,0x06}; // sending data register address
uint8_t ubNbDataToTransmit_I2C=4;
uint8_t address=0x2A;
LL_I2C_HandleTransfer(I2C1, address<<1, LL_I2C_ADDRSLAVE_7BIT,ubNbDataToTransmit_I2C, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
while(!LL_I2C_IsActiveFlag_STOP(I2C1)) { // Loop until end of transfer received (STOP // flag raised)
// Check TXIS flag value in ISR register
//Write data in Transmit Data register. TXIS flag is cleared by writing data in TXDR //register
if(LL_I2C_IsActiveFlag_TXIS(I2C1)){
LL_I2C_TransmitData8(I2C1,TxBuffer[TxIndex]);
TxIndex++;
}
}
LL_I2C_ClearFlag_STOP(I2C1);
TxIndex=0;
LL_I2C_HandleTransfer(I2C1, address<<1, LL_I2C_ADDRSLAVE_7BIT,2, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
while(!LL_I2C_IsActiveFlag_STOP(I2C1)){ // Loop until end of transfer received (STOP //flag raised)
// Check TXIS flag value in ISR register
// Write data in Transmit Data register. TXIS flag is cleared by writing data in TXDR //register
if(LL_I2C_IsActiveFlag_TXIS(I2C1)){
LL_I2C_TransmitData8(I2C1,TxBuffer1[TxIndex]);
TxIndex++;
}
}
LL_I2C_ClearFlag_STOP(I2C1);
TxIndex=0;
LL_I2C_HandleTransfer(I2C1, address<<1, LL_I2C_ADDRSLAVE_7BIT,2, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
while(!LL_I2C_IsActiveFlag_STOP(I2C1)) { // Loop until end of transfer received (STOP //flag raised)
// Check TXIS flag value in ISR register */
// Write data in Transmit Data register. TXIS flag is cleared by writing data in TXDR // register
if(LL_I2C_IsActiveFlag_RXNE(I2C1)){
BufferRX[TxIndex]=LL_I2C_ReceiveData8(I2C1);
TxIndex++;
}
}
LL_I2C_ClearFlag_STOP(I2C1);
TxIndex=0;
LL_I2C_HandleTransfer(I2C1, address<<1, LL_I2C_ADDRSLAVE_7BIT,2, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
while(!LL_I2C_IsActiveFlag_STOP(I2C1)){ // Loop until end of transfer received (STOP //flag raised)
// Check TXIS flag value in ISR register */
// Write data in Transmit Data register. TXIS flag is cleared by writing data in TXDR //register
if(LL_I2C_IsActiveFlag_RXNE(I2C1)){
BufferRX1[TxIndex]=LL_I2C_ReceiveData8(I2C1);
TxIndex++;
}
}
}
/----------SPI
void SPI_Init(void){
LL_SPI_InitTypeDef SPI_Struct;
LL_GPIO_InitTypeDef GPIO_Init_Type;
//SPI PINS MOSI PA7
GPIO_Init_Type.Pin=LL_GPIO_PIN_7;
GPIO_Init_Type.Mode=LL_GPIO_MODE_ALTERNATE;
GPIO_Init_Type.OutputType=LL_GPIO_OUTPUT_PUSHPULL;
GPIO_Init_Type.Pull=LL_GPIO_PULL_DOWN;
GPIO_Init_Type.Speed=LL_GPIO_SPEED_FREQ_VERY_HIGH;
LL_GPIO_Init(GPIOA,&GPIO_Init_Type);
//SPI PINS MISO PA6
GPIO_Init_Type.Pin=LL_GPIO_PIN_6;
GPIO_Init_Type.Mode=LL_GPIO_MODE_ALTERNATE;
GPIO_Init_Type.OutputType=LL_GPIO_OUTPUT_PUSHPULL;
GPIO_Init_Type.Pull=LL_GPIO_PULL_DOWN;
GPIO_Init_Type.Speed=LL_GPIO_SPEED_FREQ_VERY_HIGH;
LL_GPIO_Init(GPIOA,&GPIO_Init_Type);
//SPI PINS CLK PA5
GPIO_Init_Type.Pin=LL_GPIO_PIN_5;
GPIO_Init_Type.Mode=LL_GPIO_MODE_ALTERNATE;
GPIO_Init_Type.OutputType=LL_GPIO_OUTPUT_PUSHPULL;
GPIO_Init_Type.Pull=LL_GPIO_PULL_DOWN;
GPIO_Init_Type.Speed=LL_GPIO_SPEED_FREQ_VERY_HIGH;
LL_GPIO_Init(GPIOA,&GPIO_Init_Type);
//SPI PINS CS(SPI1_NSS) PA4
GPIO_Init_Type.Pin=LL_GPIO_PIN_4;
GPIO_Init_Type.Mode=LL_GPIO_MODE_OUTPUT;
GPIO_Init_Type.OutputType=LL_GPIO_OUTPUT_PUSHPULL;
GPIO_Init_Type.Pull=LL_GPIO_PULL_DOWN;
GPIO_Init_Type.Speed=LL_GPIO_SPEED_FREQ_VERY_HIGH;
LL_GPIO_Init(GPIOA,&GPIO_Init_Type);
LL_GPIO_SetAFPin_0_7(GPIOA,LL_GPIO_PIN_5,LL_GPIO_AF_5);
LL_GPIO_SetAFPin_0_7(GPIOA,LL_GPIO_PIN_7,LL_GPIO_AF_5);
LL_GPIO_SetAFPin_0_7(GPIOA,LL_GPIO_PIN_6,LL_GPIO_AF_5);
SPI_Struct.TransferDirection = LL_SPI_FULL_DUPLEX;
SPI_Struct.Mode = LL_SPI_MODE_MASTER;
SPI_Struct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
SPI_Struct.ClockPolarity = LL_SPI_POLARITY_HIGH;
SPI_Struct.ClockPhase = LL_SPI_PHASE_2EDGE;
SPI_Struct.NSS = LL_SPI_NSS_SOFT;
SPI_Struct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4;
SPI_Struct.BitOrder = LL_SPI_MSB_FIRST;
SPI_Struct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
LL_SPI_Init(SPI1,&SPI_Struct);
LL_SPI_SetRxFIFOThreshold(SPI1,LL_SPI_RX_FIFO_TH_QUARTER);
}
void Timer_Clock_Init(){
LL_TIM_InitTypeDef TIM_TimeBaseStructure;
/* Time base configuration */
TIM_TimeBaseStructure.Autoreload = 1000; //ARR value
TIM_TimeBaseStructure.Prescaler = 19999;
TIM_TimeBaseStructure.ClockDivision = 0;
TIM_TimeBaseStructure.CounterMode = LL_TIM_COUNTERMODE_UP;
LL_TIM_Init(TIM1, &TIM_TimeBaseStructure);
}
void LeptonSync(void){
int i;
uint16_t data=0x0f00;
//Setting SS high
GPIOA->ODR |= LL_GPIO_PIN_4;
Delay(186);
while (data & 0x0f == 0x0f){
//Setting SS low
GPIOA->ODR &= ~LL_GPIO_PIN_4;
//check for TX empty
while ((SPI1->SR & SPI_SR_TXE)==0){
};
//SPI tranmit 8 bits (0xFF)
LL_SPI_TransmitData8(SPI1,0x00);
//check for rx non empty
while ((SPI1->SR & SPI_SR_RXNE)==0){
};
//read the value
data=LL_SPI_ReceiveData8(SPI1);
data <<= 8;
while ((SPI1->SR & SPI_SR_TXE)==0){
};
LL_SPI_TransmitData8(SPI1,0x00);
while ((SPI1->SR & SPI_SR_RXNE)==0){
};
data |= LL_SPI_ReceiveData8(SPI1);
GPIOA->ODR |= LL_GPIO_PIN_4;
for (i = 0; i < ((VOSPI_FRAME_SIZE - 2) / 2); i++){
GPIOA->ODR &= ~LL_GPIO_PIN_4;
while ((SPI1->SR & SPI_SR_TXE)==0){
};
LL_SPI_TransmitData8(SPI1,0x00);
while ((SPI1->SR & SPI_SR_TXE)==0){
};
LL_SPI_TransmitData8(SPI1,0x00);
GPIOA->ODR |= LL_GPIO_PIN_4;
}
}
}
void Read_lepton_frame(void){
int i;
for (i = 0; i < (VOSPI_FRAME_SIZE / 2); i++){
GPIOA->ODR &= ~LL_GPIO_PIN_4;
while ((SPI1->SR & SPI_SR_TXE)==0){
};
LL_SPI_TransmitData8(SPI1,0xFF);
while ((SPI1->SR & SPI_SR_RXNE)==0){
};
lepton_frame_packet[2 * i] =LL_SPI_ReceiveData8(SPI1);
while ((SPI1->SR & SPI_SR_TXE)==0){
};
LL_SPI_TransmitData8(SPI1,0xFF);
while ((SPI1->SR & SPI_SR_RXNE)==0){
};
lepton_frame_packet[2 * i + 1] = LL_SPI_ReceiveData8(SPI1);
GPIOA->ODR |= LL_GPIO_PIN_4;
}
}
void Buffer_Image(){
uint8_t j = lepton_frame_packet[1];
IDarray[t]=j;
t++;
for (int i = 0; i < 80; i++){
//start assigning the data from 4th and 5th position to the variable image[i][j].
//Avoid assigning [0]to[3] since they are the ID and the CRC values.
for(j=0;j<60;j++){
image[i][j] = ((lepton_frame_packet[2 * i + 4] << 8) + lepton_frame_packet[2 * i + 5]);
}
if (j == 0x3B) {
donecapturing = true;
}
}
void Print_Image(){
for(int i=0;i<80;i++){
for(int j=0;j<60;j++){
wordVal=image[i][j];
Print_BitVal(wordVal);
Delay(5);
}
}
}
void send_InitBits(){
for(int i=0; i<10;i++){
while( (USART2->ISR & USART_ISR_TXE) ==0){
};
USART2 ->TDR= 0xFF;
}
}
void Print_BitVal(int16_t Val){
volatile uint16_t Val_1;
volatile uint16_t Val_2;
//take the 8 bit value
Val_1 = (Val & 0x3fc0);
Val_2 = (Val_1 >> 6);
Val_3=((Val_2>>0) & 0xff);
while( (USART2->ISR & USART_ISR_TXE) ==0){
};
USART2 ->TDR= Val_3;
}
void Delay(int n)
{
TIM1->CNT=0;
LL_TIM_EnableCounter(TIM1);
while(TIM1->CNT < n)
{};
LL_TIM_DisableCounter(TIM1);
}
//USART--------------------------
void USART_Init(){
LL_GPIO_InitTypeDef GPIO_Init_Type;
LL_USART_InitTypeDef USARTInitTypeDef;
//usart gpio pins PD6 , PD5
GPIO_Init_Type.Pin = LL_GPIO_PIN_5|LL_GPIO_PIN_6; //LL_GPIO_PIN_2;//--
GPIO_Init_Type.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_Init_Type.Pull=LL_GPIO_PULL_UP ;
GPIO_Init_Type.Speed= LL_GPIO_SPEED_FREQ_HIGH;
LL_GPIO_Init(GPIOD,&GPIO_Init_Type);
LL_GPIO_SetAFPin_0_7(GPIOD,LL_GPIO_PIN_5,LL_GPIO_AF_7);//--
LL_GPIO_SetAFPin_0_7(GPIOD,LL_GPIO_PIN_6,LL_GPIO_AF_7);
USARTInitTypeDef.BaudRate=9600;
USARTInitTypeDef.DataWidth=LL_USART_DATAWIDTH_8B;
USARTInitTypeDef.HardwareFlowControl=LL_USART_HWCONTROL_NONE;
USARTInitTypeDef.Parity=LL_USART_PARITY_NONE;
USARTInitTypeDef.StopBits= LL_USART_STOPBITS_1;
USARTInitTypeDef.TransferDirection=LL_USART_DIRECTION_TX_RX ;
USARTInitTypeDef.OverSampling=LL_USART_OVERSAMPLING_8;
LL_USART_Init(USART2,&USARTInitTypeDef);
}
void SystemClock_Config1(void)
{
/* MSI configuration and activation */
LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
LL_RCC_MSI_Enable();
while(LL_RCC_MSI_IsReady() != 1) {
};
/* Main PLL configuration and activation */
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_4, 40, LL_RCC_PLLR_DIV_2);
LL_RCC_PLL_Enable();
LL_RCC_PLL_EnableDomain_SYS();
while(LL_RCC_PLL_IsReady() != 1) {
};
/* Sysclk activation on the main PLL */
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
};
/* Set APB1 & APB2 prescaler*/
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
/* Set systick to 1ms in using frequency set to 80MHz */
/* This frequency can be calculated through LL RCC macro */
LL_Init1msTick(80000000);
/* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */
LL_SetSystemCoreClock(80000000);
}
Comments