top of page

EMBEDDED SYSTEMS

Welcome to KUS-BLOG, I started this blog to share my embedded system projects which I  did in my spare time. Explore my site and all that I have to offer; perhaps KUS-BLOG will ignite your own passions as well.

Home: Welcome
Home: Blog2
Search

FLIR Lepton Breakout Board with STM32L496ZG_NUCLEO

Kusala Bandara

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

}





Camera Captured Image of My Fist


254 views0 comments

Recent Posts

See All

Comments


CONTACT

Thanks for submitting!

Glowing Keyboard
Home: Contact
bottom of page