├── Radar RF ├── fp-info-cache ├── Radar RF-rescue.dcm ├── Radar RF.pdf ├── sym-lib-table ├── fp-lib-table ├── Radar RF └── Radar RF.pro ├── Radar MCU ├── fp-info-cache ├── Radar MCU.pdf ├── fp-lib-table ├── Radar MCU └── Radar MCU.pro ├── .gitattributes ├── Radar 2 ├── Radar v2.pdf ├── fp-lib-table ├── Radar v2-rescue.lib ├── Radar v2 └── Radar v2.pro ├── FMCW_RADAR_Firmware └── Core │ ├── CK_SYSTEM.h │ ├── CK_ADC_DMA.h │ ├── CK_MCP4022.h │ ├── CK_DAC.h │ ├── CK_TQP5523.h │ ├── USBD_CDC │ ├── usbd_cdc_if.h │ ├── usbd_desc.h │ ├── CK_USBD_INTERFACE.h │ ├── usbd_ctlreq.h │ ├── CK_USBD_BUFFER.h │ ├── usbd_ioreq.h │ ├── usbd_conf.h │ ├── CK_USBD_BUFFER.c │ ├── usbd_ioreq.c │ ├── usbd_core.h │ ├── usbd_cdc.h │ ├── usbd_cdc_if.c │ ├── CK_USBD_INTERFACE.c │ └── usbd_desc.c │ ├── CK_ADF4158.h │ ├── CK_TIME_HAL.h │ ├── CK_MAX1426.h │ ├── CK_CONFIGURATION.h │ ├── CK_SPI.h │ ├── CK_GPIO.c │ ├── CK_UART.h │ ├── CK_GPIO.h │ ├── stm32f4xx_it.h │ ├── stm32f4xx_hal_msp.c │ ├── sysmem.c │ ├── CK_MCP4022.c │ ├── CK_TIME_HAL.c │ ├── syscalls.c │ ├── CK_TQP5523.c │ ├── CK_SYSTEM.c │ ├── CK_ADC_DMA.c │ ├── stm32f4xx_it.c │ ├── CK_DAC.c │ ├── CK_UART.c │ ├── main.c │ ├── CK_SPI.c │ ├── CK_CONFIGURATION.c │ ├── CK_MAX1426.c │ └── CK_ADF4158.c ├── Radar_Python ├── Radar_Plot.py └── Radar_Record.py └── README.md /Radar RF/fp-info-cache: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /Radar MCU/fp-info-cache: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /Radar RF/Radar RF-rescue.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | #End Doc Library 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.kicad_pcb linguist-detectable=true 2 | *.sch linguist-detectable=true 3 | -------------------------------------------------------------------------------- /Radar 2/Radar v2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckflight/FMCW_RADAR/HEAD/Radar 2/Radar v2.pdf -------------------------------------------------------------------------------- /Radar RF/Radar RF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckflight/FMCW_RADAR/HEAD/Radar RF/Radar RF.pdf -------------------------------------------------------------------------------- /Radar MCU/Radar MCU.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckflight/FMCW_RADAR/HEAD/Radar MCU/Radar MCU.pdf -------------------------------------------------------------------------------- /Radar RF/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name Radar-RF-rescue)(type Legacy)(uri "${KIPRJMOD}/Radar RF-rescue.lib")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /Radar 2/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name Footprints)(type KiCad)(uri "/Users/ck/Desktop/Workspace/Kicad Workspace/_LIBRARY AND FOOTPRINT/Footprints.pretty")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /Radar MCU/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name Footprints)(type KiCad)(uri "/Users/ck/Desktop/Workspace/Kicad Workspace/_LIBRARY AND FOOTPRINT/Footprints.pretty")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /Radar RF/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name Footprints)(type KiCad)(uri "/Users/ck/Desktop/Workspace/Kicad Workspace/_LIBRARY AND FOOTPRINT/Footprints.pretty")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_SYSTEM.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CK_SYSTEM_H_ 3 | #define CK_SYSTEM_H_ 4 | 5 | #include "stm32f4xx.h" 6 | 7 | uint32_t F_CPU; // CK_TIME_HAL uses 8 | 9 | typedef enum{ 10 | 11 | SYSTEM_CLK_180MHz, 12 | 13 | SYSTEM_CLK_168MHz 14 | 15 | }systemClock_e; 16 | 17 | void CK_SYSTEM_SetSystemClock(systemClock_e clk); 18 | 19 | uint32_t CK_SYSTEM_GetSystemClock(void); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_ADC_DMA.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef INC_CK_ADC_DMA_H_ 3 | #define INC_CK_ADC_DMA_H_ 4 | 5 | void CK_ADC_DMA_Init(void); 6 | 7 | void CK_ADC_DMA_Start(void); 8 | 9 | void CK_ADC_DMA_DMAStop(void); 10 | 11 | void CK_ADC_DMA_DMAStart(void); 12 | 13 | void CK_ADC_DMA_ADCStop(void); 14 | 15 | void CK_ADC_DMA_ADCStart(void); 16 | 17 | int CK_ADC_DMA_IsTxComplete(void); 18 | 19 | void CK_ADC_DMA_TransferSamples(void); 20 | 21 | #endif /* INC_CK_ADC_DMA_H_ */ 22 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_MCP4022.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CK_MCP4022_H_ 3 | #define CK_MCP4022_H_ 4 | 5 | #include "stm32f4xx.h" 6 | 7 | void MCP4022_Init(void); 8 | 9 | void MCP4022_UD_High(void); 10 | 11 | void MCP4022_UD_Low(void); 12 | 13 | void MCP4022_CS_High(void); 14 | 15 | void MCP4022_CS_Low(void); 16 | 17 | void MCP4022_SetValue(uint8_t new_value); 18 | 19 | void MCP4022_Increase(uint8_t value); 20 | 21 | void MCP4022_Decrease(uint8_t value); 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_DAC.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CK_DAC_H_ 3 | #define CK_DAC_H_ 4 | 5 | #include "stm32f4xx.h" 6 | 7 | uint32_t dac_timer_t1, dac_timer_t2; 8 | 9 | typedef enum{ 10 | 11 | SAWTOOTH_WAVEFORM_DAC, 12 | TRIANGULAR_WAVEFORM_DAC 13 | 14 | }RAMP_TYPE; 15 | 16 | void CK_DAC_Init(RAMP_TYPE ramp); 17 | 18 | void CK_DAC_TIMER_Init(void); 19 | 20 | void CK_DAC_LoadValue(uint16_t value); 21 | 22 | void CK_DAC_Sawtooth(void); 23 | 24 | void CK_DAC_Triangular(void); 25 | 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_TQP5523.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef INC_CK_TQP5523_H_ 3 | #define INC_CK_TQP5523_H_ 4 | 5 | #include "stm32f4xx.h" 6 | 7 | void CK_TQP5523_Init(void); 8 | 9 | void CK_TQP5523_Update(void); 10 | 11 | void CK_TQP5523_CheckOutputPower(void); 12 | 13 | void CK_TQP5523_StartConversion(void); 14 | 15 | void CK_TQP5523_Disable(void); 16 | 17 | void CK_TQP5523_Enable(void); 18 | 19 | float CK_TQP5523_ReadDetectorOutputVoltage(void); 20 | 21 | int CK_TQP5523_ReadDetectorOutputDBM(void); 22 | 23 | #endif /* INC_CK_TQP5523_H_ */ 24 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_cdc_if.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __USBD_CDC_IF_H__ 3 | #define __USBD_CDC_IF_H__ 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | /* Includes ------------------------------------------------------------------*/ 10 | #include "USBD_CDC/usbd_cdc.h" 11 | 12 | 13 | /** CDC Interface callback. */ 14 | extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; 15 | 16 | uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); 17 | 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_ADF4158.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef INC_CK_ADF4158_H_ 3 | #define INC_CK_ADF4158_H_ 4 | 5 | #include "stm32f4xx.h" 6 | 7 | typedef enum{ 8 | SAWTOOTH_WAVEFORM, 9 | TRIANGULAR_WAVEFORM 10 | 11 | }WAVEFORM_TYPE; 12 | 13 | 14 | void CK_ADF4158_Init(WAVEFORM_TYPE wf); 15 | 16 | void CK_ADF4158_Configure_Sweep(WAVEFORM_TYPE wf, double startFreq, double bw, double rampTime, int rampDel); 17 | 18 | void CK_ADF4158_WriteRegister(uint32_t data); 19 | 20 | void CK_ADF4158_DeviceEnable(void); 21 | 22 | uint32_t CK_ADF4158_GetPulseReceived(void); 23 | 24 | int CK_ADF4158_RampStarted(void); 25 | 26 | int CK_ADF4158_RampCompleted(void); 27 | 28 | #endif /* INC_CK_ADF4158_H_ */ 29 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_desc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __USBD_DESC__C__ 3 | #define __USBD_DESC__C__ 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | /* Includes ------------------------------------------------------------------*/ 10 | #include "USBD_CDC/usbd_def.h" 11 | 12 | #define DEVICE_ID1 (UID_BASE) 13 | #define DEVICE_ID2 (UID_BASE + 0x4) 14 | #define DEVICE_ID3 (UID_BASE + 0x8) 15 | 16 | #define USB_SIZ_STRING_SERIAL 0x1A 17 | 18 | /** Descriptor for the Usb device. */ 19 | extern USBD_DescriptorsTypeDef FS_Desc; 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_TIME_HAL.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CK_TIME_HAL_H_ 3 | #define CK_TIME_HAL_H_ 4 | 5 | 6 | void CK_TIME_SetTimeOut(uint32_t time); 7 | 8 | uint32_t CK_TIME_GetTimeOut(void); 9 | 10 | void HAL_IncTick(void); 11 | 12 | uint32_t HAL_GetTick(void); 13 | 14 | uint32_t CK_TIME_GetMicroSec_SYSTICK(void); 15 | 16 | uint32_t CK_TIME_GetMilliSec_SYSTICK(void); 17 | 18 | uint32_t CK_TIME_GetMicroSec_DWT(void); 19 | 20 | uint32_t CK_TIME_GetMilliSec_DWT(void); 21 | 22 | uint32_t CK_TIME_GetMicroSec(void); 23 | 24 | uint32_t CK_TIME_GetMilliSec(void); 25 | 26 | void CK_TIME_DelayMilliSec(uint32_t msec); 27 | 28 | void CK_TIME_DelayMicroSec(uint32_t usec); 29 | 30 | #endif /* CK_TIME_HAL_H_ */ 31 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_MAX1426.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef INC_CK_MAX1426_H_ 3 | #define INC_CK_MAX1426_H_ 4 | 5 | #include "stm32f4xx.h" 6 | 7 | void CK_MAX1426_Init(void); 8 | 9 | 10 | void CK_MAX1426_EXTI_Init(void); 11 | 12 | void TIMER1_Init(void); 13 | 14 | void CK_MAX1426_PWM_Init(void); 15 | 16 | void CK_MAX1426_PWM_Start(void); 17 | 18 | void CK_MAX1426_PWM_Stop(void); 19 | 20 | void CK_MAX1426_ADC_OutputDisable(void); 21 | 22 | void CK_MAX1426_ADC_OutputEnable(void); 23 | 24 | uint16_t CK_MAX1426_Get_ADCResult(void); 25 | 26 | uint16_t CK_MAX1426_Get_Counter(void); 27 | 28 | void CK_MAX1426_Reset_Counter(void); 29 | 30 | uint8_t CK_MAX1426_IsRecordDone(void); 31 | 32 | void CK_MAX1426_ResetRecordDone(void); 33 | 34 | void CK_MAX1426_TransferSamples(void); 35 | 36 | #endif /* INC_CK_MAX1426_H_ */ 37 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/CK_USBD_INTERFACE.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __USB_DEVICE__H__ 3 | #define __USB_DEVICE__H__ 4 | 5 | #include "stm32f4xx.h" 6 | #include "stm32f4xx_hal.h" 7 | #include "USBD_CDC/usbd_def.h" 8 | 9 | void CK_USBD_Init(void); 10 | 11 | void CK_USBD_Start(void); 12 | 13 | void CK_USBD_Stop(void); 14 | 15 | int CK_USBD_Transmit(void); 16 | 17 | int CK_USBD_ReadData(uint8_t* data); 18 | 19 | int CK_USBD_WriteRxCircularBuffer(uint8_t* Buf, uint32_t* Len); 20 | 21 | int CK_USBD_WriteTxCircularBuffer(uint8_t data); 22 | 23 | void CK_USBD_ClearBufferIndex(void); 24 | 25 | void CK_USBD_IntPrint(int32_t num); 26 | 27 | void CK_USBD_IntPrintln(int32_t num); 28 | 29 | void CK_USBD_FloatPrintln(float num); 30 | 31 | void CK_USBD_FloatPrint(float num); 32 | 33 | void CK_USBD_StringPrintln(const char str[]); 34 | 35 | void CK_USBD_StringPrint(const char str[]); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_ctlreq.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __USB_REQUEST_H 3 | #define __USB_REQUEST_H 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | /* Includes ------------------------------------------------------------------*/ 10 | #include "USBD_CDC/usbd_def.h" 11 | 12 | USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); 13 | USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); 14 | USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); 15 | 16 | 17 | void USBD_CtlError (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); 18 | 19 | void USBD_ParseSetupRequest (USBD_SetupReqTypedef *req, uint8_t *pdata); 20 | 21 | void USBD_GetString (uint8_t *desc, uint8_t *unicode, uint16_t *len); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/CK_USBD_BUFFER.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CK_CIRCULARBUFFER_H_ 3 | #define CK_CIRCULARBUFFER_H_ 4 | 5 | #include "stdbool.h" 6 | 7 | typedef struct { 8 | 9 | uint8_t * buffer; 10 | int head; 11 | int tail; 12 | int size; 13 | 14 | }circularBuffer_t; 15 | 16 | void CK_USBD_BUFFER_Init(circularBuffer_t* cb, int size); 17 | 18 | int CK_USBD_BUFFER_BufferWrite(circularBuffer_t* c, uint8_t data); 19 | 20 | int CK_USBD_BUFFER_BufferWriteMulti(circularBuffer_t* c, uint8_t* buff, uint32_t length); 21 | 22 | int CK_USBD_BUFFER_BufferRead(circularBuffer_t* c, uint8_t* data); 23 | 24 | void CK_USBD_BUFFER_GetBuffer(circularBuffer_t* c, uint8_t* buff, uint32_t* numOfElement); 25 | 26 | int CK_USBD_BUFFER_GetAvailable(circularBuffer_t* c); 27 | 28 | bool CK_USBD_BUFFER_IsBufferEmpty(circularBuffer_t* c); 29 | 30 | bool CK_USBD_BUFFER_IsBufferFull(circularBuffer_t* c); 31 | 32 | #endif /* CK_CIRCULARBUFFER_H_ */ 33 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_CONFIGURATION.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef INC_CK_CONFIGURATION_H_ 3 | #define INC_CK_CONFIGURATION_H_ 4 | 5 | #include "stm32f4xx.h" 6 | 7 | void CK_CONFIGURATION_Init(void); 8 | 9 | void CK_CONFIGURATION_InitHardware(uint8_t mode); 10 | 11 | uint32_t CK_CONFIGURATION_GetRecordTimeCounter(void); 12 | 13 | uint8_t CK_CONFIGURATION_GetRecordTime(void); 14 | 15 | uint32_t CK_CONFIGURATION_GetSweepTime(void); 16 | 17 | uint32_t CK_CONFIGURATION_GetSweepGap(void); 18 | 19 | uint32_t CK_CONFIGURATION_GetSamplingFrequency(void); 20 | 21 | uint32_t CK_CONFIGURATION_GetSampleNumber(void); 22 | 23 | uint32_t CK_CONFIGURATION_GetSweepStartFrequency(void); 24 | 25 | uint32_t CK_CONFIGURATION_GetSweepBandwith(void); 26 | 27 | uint8_t CK_CONFIGURATION_GetTXMode(void); 28 | 29 | uint8_t CK_CONFIGURATION_GetGainValue(void); 30 | 31 | uint8_t CK_CONFIGURATION_SweepType(void); 32 | 33 | uint8_t CK_CONFIGURATION_DecodeData(uint8_t rx_data); 34 | 35 | 36 | 37 | #endif /* INC_CK_CONFIGURATION_H_ */ 38 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_ioreq.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __USBD_IOREQ_H 3 | #define __USBD_IOREQ_H 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | /* Includes ------------------------------------------------------------------*/ 10 | #include "USBD_CDC/usbd_def.h" 11 | #include "USBD_CDC/usbd_core.h" 12 | 13 | USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, 14 | uint8_t *pbuf, 15 | uint16_t len); 16 | 17 | USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, 18 | uint8_t *pbuf, 19 | uint16_t len); 20 | 21 | USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev, 22 | uint8_t *pbuf, 23 | uint16_t len); 24 | 25 | USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, 26 | uint8_t *pbuf, 27 | uint16_t len); 28 | 29 | USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev); 30 | 31 | USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev); 32 | 33 | uint32_t USBD_GetRxCount (USBD_HandleTypeDef *pdev, uint8_t ep_addr); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_SPI.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CK_SPI_H_ 3 | #define CK_SPI_H_ 4 | 5 | #include "stm32f4xx.h" 6 | 7 | typedef enum 8 | { 9 | CK_SPIx_CR1_Fclk_Div2 = 0u<<3, 10 | CK_SPIx_CR1_Fclk_Div4 = 1u<<3, 11 | CK_SPIx_CR1_Fclk_Div8 = 2u<<3, 12 | CK_SPIx_CR1_Fclk_Div16 = 3u<<3, 13 | CK_SPIx_CR1_Fclk_Div32 = 4u<<3, 14 | CK_SPIx_CR1_Fclk_Div64 = 5u<<3, 15 | CK_SPIx_CR1_Fclk_Div128 = 6u<<3, 16 | CK_SPIx_CR1_Fclk_Div256 = 7u<<3 17 | 18 | }CK_SPIx_CR1_Fclk_Div; 19 | 20 | void CK_SPI_Init(SPI_TypeDef* spi_n); 21 | 22 | void CK_SPI_Enable(SPI_TypeDef* spi_n); 23 | 24 | void CK_SPI_Disable(SPI_TypeDef* spi_n); 25 | 26 | void CK_SPI_EnableDMA(SPI_TypeDef* spi_n); 27 | 28 | void CK_SPI_DisableDMA(SPI_TypeDef* spi_n); 29 | 30 | void CK_SPI_ChangeClock(SPI_TypeDef* spi_n, CK_SPIx_CR1_Fclk_Div clk); 31 | 32 | uint8_t CK_SPI_WriteRegister(uint8_t reg, uint8_t data, SPI_TypeDef* SPIn, GPIO_TypeDef* GPIOx_CS, uint16_t cs_pin); 33 | 34 | void CK_SPI_ReadRegisterMulti(uint8_t reg, SPI_TypeDef* SPIn, GPIO_TypeDef* GPIOx_CS, uint16_t cs_pin, uint8_t* dataIn, int count); 35 | 36 | uint8_t CK_SPI_Transfer(SPI_TypeDef* SPIn, uint8_t data); 37 | 38 | uint8_t CK_SPI_WaitTransfer(SPI_TypeDef* SPIn); 39 | 40 | int CK_SPI_CheckInitialized(SPI_TypeDef* SPIn); 41 | 42 | void CK_SPI_TimeOutCounter(SPI_TypeDef* spi); 43 | 44 | uint32_t CK_SPI_GetTimeOut(SPI_TypeDef* spi); 45 | 46 | void CK_SPI_ResetTimeOut(SPI_TypeDef* spi); 47 | 48 | #endif /* CK_SPI_H_ */ 49 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_GPIO.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_GPIO.h" 3 | 4 | void CK_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIOx_Pin, CK_GPIOx_Mode GPIOx_Mode, CK_GPIOx_AFx GPIOx_AF, 5 | CK_GPIOx_Type GPIOx_Type, CK_GPIOx_Speed GPIOx_Speed, CK_GPIOx_PUPD GPIOx_PUPD) 6 | { 7 | if(GPIOx_Mode == CK_GPIO_OUTPUT || GPIOx_Mode == CK_GPIO_AF){ 8 | 9 | if(GPIOx_AF != CK_GPIO_NOAF){ 10 | if(GPIOx_Pin < 8){ 11 | GPIOx->AFR[0] |= GPIOx_AF<<(GPIOx_Pin*4); 12 | } 13 | else{ 14 | GPIOx->AFR[1] |= GPIOx_AF<<((GPIOx_Pin-8)*4); 15 | } 16 | } 17 | } 18 | 19 | GPIOx->MODER |= GPIOx_Mode << (GPIOx_Pin*2); 20 | GPIOx->OSPEEDR |= GPIOx_Speed<<(GPIOx_Pin*2); 21 | 22 | if(GPIOx_Type == CK_GPIO_PUSHPULL){ 23 | GPIOx->OTYPER &= ~(1u<OTYPER |= 1u<PUPDR &= ~(3u<<(GPIOx_Pin*2)); 31 | } 32 | else{ 33 | GPIOx->PUPDR |= GPIOx_PUPD<<(GPIOx_Pin*2); 34 | } 35 | 36 | } 37 | 38 | void CK_GPIO_ClockEnable(GPIO_TypeDef* GPIOx){ 39 | uint16_t port_clk = ((uint32_t)GPIOx - (GPIOA_BASE)) / ((GPIOB_BASE) - (GPIOA_BASE)); 40 | RCC->AHB1ENR |= 1u<BSRR |= 1u<BSRR |= 1u<<(GPIOx_Pin+16); 52 | 53 | } 54 | 55 | uint8_t CK_GPIO_ReadPin(GPIO_TypeDef* GPIOx ,uint16_t GPIOx_Pin){ 56 | 57 | uint16_t temp = (GPIOx->IDR & (uint16_t)(1u<> GPIOx_Pin; 58 | 59 | if(temp == 0x01){ 60 | return 0x01; 61 | } 62 | return 0x00; 63 | 64 | } 65 | 66 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_UART.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CK_UART_H_ 3 | #define CK_UART_H_ 4 | 5 | #include "stm32f4xx.h" 6 | //#include "CK_CIRCULARBUFFER.h" 7 | #include "CK_GPIO.h" 8 | //#include "CK_SBUS.h" 9 | 10 | //circularBuffer_t cb; 11 | 12 | #define CK_RCC_APB2ENR_USART1 1u<<4 //USART1 CLK ENABLE 13 | #define CK_RCC_APB1ENR_USART3 1u<<18 //USART3 CLK ENABLE 14 | #define CK_RCC_APB1ENR_UART5 1u<<20 //UART5 CLK ENABLE 15 | 16 | #define CK_USART_CR1_TE 1u<<3 //TX ENABLE 17 | #define CK_USART_CR1_RE 1u<<2 //RX ENABLE 18 | #define CK_USART_CR1_RXNEIE 1u<<5 //Receive Interrupt Enable 19 | #define CK_USART_CR1_UE 1u<<13 //USART ENABLE 20 | #define CK_USART_CR1_OVER8 1u<<15 //OVER SAMPLING 8 21 | #define CK_USART_CR1_PCE 1u<<10 //PARITY ENABLED 22 | #define CK_USART_CR1_PS 1u<<9 //PARITY SELECT 0=EVEN,1=ODD 23 | 24 | #define CK_USART_CR2_STOP_2Bit 2u<<12 //2 Stop Bits 25 | 26 | #define CK_USART_SR_TXE 1u<<7 //TX BUFFER EMPTY 27 | #define CK_USART_SR_TC 1u<<6 //TRANSFER COMPLETE 28 | #define CK_USART_SR_RXNE 1u<<5 //RECEIVE COMPLETE 29 | 30 | #define CK_BufferSize 32 31 | 32 | typedef enum{ 33 | 34 | SBUS_INACTIVE =0, 35 | SBUS_ACTIVE =1 36 | 37 | }SBUS_MODE; 38 | 39 | uint8_t CK_TXBuffer_int16[CK_BufferSize]; 40 | uint8_t CK_TXBuffer_int[CK_BufferSize]; 41 | uint8_t CK_TXBuffer_float[CK_BufferSize]; 42 | 43 | void CK_UART_Init1(int baudRate); 44 | 45 | void CK_USART1Send(uint8_t chr[],int size); 46 | 47 | void CK_IntPrintln(int num); 48 | void CK_IntPrint(int num); 49 | 50 | void CK_Int16Println(int16_t num); 51 | void CK_Int16Print(int16_t num); 52 | 53 | void CK_FloatPrintln(float num); 54 | void CK_FloatPrint(float num); 55 | 56 | void CK_StringPrintln(const char str[]); 57 | void CK_StringPrint(const char str[]); 58 | 59 | int CK_getArraySize(const char arry[]); 60 | 61 | #endif /* CK_UART_H_ */ 62 | -------------------------------------------------------------------------------- /Radar 2/Radar v2-rescue.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.4 2 | #encoding utf-8 3 | # 4 | # +10V-+10V 5 | # 6 | DEF +10V-+10V #PWR 0 0 Y Y 1 F P 7 | F0 "#PWR" 0 -150 50 H I C CNN 8 | F1 "+10V-+10V" 0 150 39 H V C CNN 9 | F2 "" 0 0 50 H I C CNN 10 | F3 "" 0 0 50 H I C CNN 11 | DRAW 12 | P 2 0 1 0 -30 75 0 125 N 13 | P 2 0 1 0 0 0 0 100 N 14 | P 2 0 1 0 0 100 0 125 N 15 | P 2 0 1 0 0 125 30 75 N 16 | X +10V 1 0 0 0 U 50 50 1 1 W N 17 | ENDDRAW 18 | ENDDEF 19 | # 20 | # +2.5V-+2.5V 21 | # 22 | DEF +2.5V-+2.5V #PWR 0 0 Y Y 1 F P 23 | F0 "#PWR" 0 -150 50 H I C CNN 24 | F1 "+2.5V-+2.5V" 0 150 39 H V C CNN 25 | F2 "" 0 0 50 H I C CNN 26 | F3 "" 0 0 50 H I C CNN 27 | DRAW 28 | P 2 0 1 0 -30 75 0 125 N 29 | P 2 0 1 0 0 0 0 100 N 30 | P 2 0 1 0 0 100 0 125 N 31 | P 2 0 1 0 0 125 30 75 N 32 | X +2V5 1 0 0 0 U 50 50 1 1 W N 33 | ENDDRAW 34 | ENDDEF 35 | # 36 | # +3.0V-+3.0V 37 | # 38 | DEF +3.0V-+3.0V #PWR 0 0 Y Y 1 F P 39 | F0 "#PWR" 0 -150 50 H I C CNN 40 | F1 "+3.0V-+3.0V" 0 150 39 H V C CNN 41 | F2 "" 0 0 50 H I C CNN 42 | F3 "" 0 0 50 H I C CNN 43 | DRAW 44 | P 2 0 1 0 -30 75 0 125 N 45 | P 2 0 1 0 0 0 0 100 N 46 | P 2 0 1 0 0 100 0 125 N 47 | P 2 0 1 0 0 125 30 75 N 48 | X +3V0 1 0 0 0 U 50 50 1 1 W N 49 | ENDDRAW 50 | ENDDEF 51 | # 52 | # +3.3V-+3.3V 53 | # 54 | DEF +3.3V-+3.3V #PWR 0 0 Y Y 1 F P 55 | F0 "#PWR" 0 -150 50 H I C CNN 56 | F1 "+3.3V-+3.3V" 0 150 39 H V C CNN 57 | F2 "" 0 0 50 H I C CNN 58 | F3 "" 0 0 50 H I C CNN 59 | DRAW 60 | P 2 0 1 0 -30 75 0 125 N 61 | P 2 0 1 0 0 0 0 100 N 62 | P 2 0 1 0 0 100 0 125 N 63 | P 2 0 1 0 0 125 30 75 N 64 | X +3V3 1 0 0 0 U 50 50 1 1 W N 65 | ENDDRAW 66 | ENDDEF 67 | # 68 | # +5V-+5V 69 | # 70 | DEF +5V-+5V #PWR 0 0 Y Y 1 F P 71 | F0 "#PWR" 0 -150 50 H I C CNN 72 | F1 "+5V-+5V" 0 150 39 H V C CNN 73 | F2 "" 0 0 50 H I C CNN 74 | F3 "" 0 0 50 H I C CNN 75 | DRAW 76 | P 2 0 1 0 -30 75 0 125 N 77 | P 2 0 1 0 0 0 0 100 N 78 | P 2 0 1 0 0 100 0 125 N 79 | P 2 0 1 0 0 125 30 75 N 80 | X +5V 1 0 0 0 U 50 50 1 1 W N 81 | ENDDRAW 82 | ENDDEF 83 | # 84 | #End Library 85 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_GPIO.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CK_GPIO_H_ 3 | #define CK_GPIO_H_ 4 | 5 | #include "stm32f4xx.h" 6 | 7 | typedef enum 8 | { 9 | CK_GPIO_INPUT = 0u, 10 | CK_GPIO_OUTPUT = 1u, 11 | CK_GPIO_AF = 2u, 12 | CK_GPIO_ANALOG = 3u 13 | 14 | }CK_GPIOx_Mode; 15 | 16 | typedef enum 17 | { 18 | CK_GPIO_PUSHPULL = 0u, 19 | CK_GPIO_OPENDRAIN = 1u 20 | 21 | }CK_GPIOx_Type; 22 | 23 | typedef enum 24 | { 25 | CK_GPIO_LOW = 0u, 26 | CK_GPIO_MEDIUM = 1u, 27 | CK_GPIO_HIGH = 2u, 28 | CK_GPIO_VERYHIGH = 3u 29 | 30 | }CK_GPIOx_Speed; 31 | 32 | typedef enum 33 | { 34 | CK_GPIO_NOPUPD = 0u, 35 | CK_GPIO_PULLUP = 1u, 36 | CK_GPIO_PULLDOWN = 2u 37 | 38 | }CK_GPIOx_PUPD; 39 | 40 | 41 | typedef enum 42 | { 43 | CK_GPIO_AF0 = 0u, 44 | CK_GPIO_AF1 = 1u, 45 | CK_GPIO_AF2 = 2u, 46 | CK_GPIO_AF3 = 3u, 47 | CK_GPIO_AF4 = 4u, 48 | CK_GPIO_AF5 = 5u, 49 | CK_GPIO_AF6 = 6u, 50 | CK_GPIO_AF7 = 7u, 51 | CK_GPIO_AF8 = 8u, 52 | CK_GPIO_AF9 = 9u, 53 | CK_GPIO_AF10 = 0xAu, 54 | CK_GPIO_AF11 = 0xBu, 55 | CK_GPIO_AF12 = 0xCu, 56 | CK_GPIO_AF13 = 0xDu, 57 | CK_GPIO_AF14 = 0xEu, 58 | CK_GPIO_AF15 = 0xFu, 59 | CK_GPIO_NOAF = 0x10u 60 | 61 | }CK_GPIOx_AFx; 62 | 63 | void CK_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIOx_Pin, CK_GPIOx_Mode GPIOx_Mode, CK_GPIOx_AFx GPIOx_AF, 64 | CK_GPIOx_Type GPIOx_Type, CK_GPIOx_Speed GPIOx_Speed, CK_GPIOx_PUPD GPIOx_PUPD); 65 | 66 | void CK_GPIO_ClockEnable(GPIO_TypeDef* GPIOx); 67 | 68 | void CK_GPIO_SetPin(GPIO_TypeDef* GPIOx,uint16_t GPIOx_Pin); 69 | 70 | void CK_GPIO_ClearPin(GPIO_TypeDef* GPIOx,uint16_t GPIOx_Pin); 71 | 72 | uint8_t CK_GPIO_ReadPin(GPIO_TypeDef* GPIOx ,uint16_t GPIOx_Pin); 73 | 74 | #endif /* CK_GPIO_H_ */ 75 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/stm32f4xx_it.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f4xx_it.h 5 | * @brief This file contains the headers of the interrupt handlers. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2020 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Define to prevent recursive inclusion -------------------------------------*/ 22 | #ifndef __STM32F4xx_IT_H 23 | #define __STM32F4xx_IT_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* Private includes ----------------------------------------------------------*/ 30 | /* USER CODE BEGIN Includes */ 31 | 32 | /* USER CODE END Includes */ 33 | 34 | /* Exported types ------------------------------------------------------------*/ 35 | /* USER CODE BEGIN ET */ 36 | 37 | /* USER CODE END ET */ 38 | 39 | /* Exported constants --------------------------------------------------------*/ 40 | /* USER CODE BEGIN EC */ 41 | 42 | /* USER CODE END EC */ 43 | 44 | /* Exported macro ------------------------------------------------------------*/ 45 | /* USER CODE BEGIN EM */ 46 | 47 | /* USER CODE END EM */ 48 | 49 | /* Exported functions prototypes ---------------------------------------------*/ 50 | void NMI_Handler(void); 51 | void HardFault_Handler(void); 52 | void MemManage_Handler(void); 53 | void BusFault_Handler(void); 54 | void UsageFault_Handler(void); 55 | void SVC_Handler(void); 56 | void DebugMon_Handler(void); 57 | void PendSV_Handler(void); 58 | void SysTick_Handler(void); 59 | /* USER CODE BEGIN EFP */ 60 | 61 | /* USER CODE END EFP */ 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif /* __STM32F4xx_IT_H */ 68 | 69 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 70 | -------------------------------------------------------------------------------- /Radar MCU/Radar MCU: -------------------------------------------------------------------------------- 1 | Reference, Quantity, Value, Footprint, Datasheet 2 | 3 | C15 C2 C28 C1 ,4,"10uF","Footprints:SMD_0603","" 4 | 5 | C19 C20 C17 C16 C11 C5 C29 ,7,"2.2uF","Footprints:SMD_0402","" 6 | 7 | C21 C22 ,2,"15pF","Footprints:SMD_0402","" 8 | 9 | C25 C38 ,2,"33pF","Footprints:SMD_0402","" 10 | 11 | C27 C13 C14 C12 C31 C36 C30 C35 C37 C34 C42 C41 C26 C23 C24 C18 ,16,"100nF","Footprints:SMD_0402","" 12 | 13 | C3 C9 C43 C44 C6 ,5,"22uF","Footprints:SMD_0603","" 14 | 15 | C33 C32 ,2,"100pF","Footprints:SMD_0402","" 16 | 17 | C39 C40 ,2,"1uF","Footprints:SMD_0402","" 18 | 19 | C7 C10 C4 ,3,"10nF","Footprints:SMD_0402","" 20 | 21 | D1 D2 ,2,"SDM2U30CSP_7","Footprints:Diode_SDM2U30CSP_7","" 22 | 23 | D3 D4 D5 ,3,"Led_Diode","Footprints:Diode_0603","" 24 | 25 | J1 ,1,"SWD_DEBUGGER","Footprints:PinHeader_1x5_P2.54mm","" 26 | 27 | J2 ,1,"Connector_01x02","Footprints:PinHeader_1x2_P2.54mm","" 28 | 29 | J3 ,1,"USB_MicroB","Footprints:USB_MicroB_TH","" 30 | 31 | J4 ,1,"Connector_02x15","Footprints:PinHeader_2x15_DF12B(5.0)-30DP-0.5V(86)","" 32 | 33 | J5 ,1,"GPIO_EXTRA","Footprints:PinHeader_1x5_P2.54mm","" 34 | 35 | L1 L2 ,2,"4.7uH","Footprints:SMD_0805","" 36 | 37 | Q2 Q1 ,2,"BSS138","Footprints:SOT23_3","" 38 | 39 | R1 R2 R16 ,3,"22","Footprints:SMD_0402","" 40 | 41 | R15 R19 ,2,"2.49K","Footprints:SMD_0402","" 42 | 43 | R17 R24 R28 R29 R7 R8 ,6,"10K","Footprints:SMD_0402","" 44 | 45 | R18 R13 R14 R20 R32 R33 R34 ,7,"1K","Footprints:SMD_0402","" 46 | 47 | R21 ,1,"49.9","Footprints:SMD_0402","" 48 | 49 | R22 R5 R6 ,3,"100","Footprints:SMD_0402","" 50 | 51 | R25 R11 R12 ,3,"DNP","Footprints:SMD_0402","" 52 | 53 | R26 R9 R10 ,3,"0","Footprints:SMD_0402","" 54 | 55 | R3 ,1,"14.7K","Footprints:SMD_0402","" 56 | 57 | R30 ,1,"24.4K","Footprints:SMD_0402","" 58 | 59 | R4 R27 R23 R31 ,4,"4.7K","Footprints:SMD_0402","" 60 | 61 | SW1 ,1,"DFU_Button","Footprints:Button_B3U_1000P","" 62 | 63 | SW2 ,1,"Reset_Button","Footprints:Button_B3U_1000P","" 64 | 65 | U2 U1 ,2,"AP3211","Footprints:SOT23_6","" 66 | 67 | U3 ,1,"LP2985_10","Footprints:SOT23_5","" 68 | 69 | U4 ,1,"STM32F405","Footprints:LQFP64_10x10mm_P0.5mm","" 70 | 71 | U5 ,1,"IF+","Footprints:SolderPad_1_1.5mm_SMD_Rectangle","" 72 | 73 | U6 ,1,"IF-","Footprints:SolderPad_1_1.5mm_SMD_Rectangle","" 74 | 75 | U7 ,1,"MCP4022_202","Footprints:SOT23_6","" 76 | 77 | U8 ,1,"LT1817","Footprints:SSOP16_3.9x4.9mm_P0.635mm","" 78 | 79 | U9 ,1,"MAX1426","Footprints:SSOP28_5.3x10.2mm_P0.65mm","" 80 | 81 | Y1 ,1,"8MHz","Footprints:Crystal_3.2x2.5mm","" 82 | 83 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_conf.h: -------------------------------------------------------------------------------- 1 | 2 | /* Define to prevent recursive inclusion -------------------------------------*/ 3 | #ifndef __USBD_CONF__H__ 4 | #define __USBD_CONF__H__ 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /* Includes ------------------------------------------------------------------*/ 11 | #include "stdio.h" 12 | #include "stdlib.h" 13 | #include "string.h" 14 | 15 | #include "stm32f4xx.h" 16 | #include "stm32f4xx_hal.h" 17 | 18 | /*---------- -----------*/ 19 | #define USBD_MAX_NUM_INTERFACES 1U 20 | /*---------- -----------*/ 21 | #define USBD_MAX_NUM_CONFIGURATION 1U 22 | /*---------- -----------*/ 23 | #define USBD_MAX_STR_DESC_SIZ 512U 24 | /*---------- -----------*/ 25 | #define USBD_SUPPORT_USER_STRING 0U 26 | /*---------- -----------*/ 27 | #define USBD_DEBUG_LEVEL 0U 28 | /*---------- -----------*/ 29 | #define USBD_LPM_ENABLED 0U 30 | /*---------- -----------*/ 31 | #define USBD_SELF_POWERED 1U 32 | 33 | /****************************************/ 34 | /* #define for FS and HS identification */ 35 | #define DEVICE_FS 0 36 | #define DEVICE_HS 1 37 | 38 | /** @defgroup USBD_CONF_Exported_Macros USBD_CONF_Exported_Macros 39 | * @brief Aliases. 40 | * @{ 41 | */ 42 | 43 | /* Memory management macros */ 44 | 45 | /** Alias for memory allocation. */ 46 | #define USBD_malloc malloc 47 | 48 | /** Alias for memory release. */ 49 | #define USBD_free free 50 | 51 | /** Alias for memory set. */ 52 | #define USBD_memset memset 53 | 54 | /** Alias for memory copy. */ 55 | #define USBD_memcpy memcpy 56 | 57 | /** Alias for delay. */ 58 | #define USBD_Delay HAL_Delay 59 | 60 | /* DEBUG macros */ 61 | 62 | #if (USBD_DEBUG_LEVEL > 0) 63 | #define USBD_UsrLog(...) printf(__VA_ARGS__);\ 64 | printf("\n"); 65 | #else 66 | #define USBD_UsrLog(...) 67 | #endif 68 | 69 | #if (USBD_DEBUG_LEVEL > 1) 70 | 71 | #define USBD_ErrLog(...) printf("ERROR: ") ;\ 72 | printf(__VA_ARGS__);\ 73 | printf("\n"); 74 | #else 75 | #define USBD_ErrLog(...) 76 | #endif 77 | 78 | #if (USBD_DEBUG_LEVEL > 2) 79 | #define USBD_DbgLog(...) printf("DEBUG : ") ;\ 80 | printf(__VA_ARGS__);\ 81 | printf("\n"); 82 | #else 83 | #define USBD_DbgLog(...) 84 | #endif 85 | 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/stm32f4xx_hal_msp.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * File Name : stm32f4xx_hal_msp.c 5 | * Description : This file provides code for the MSP Initialization 6 | * and de-Initialization codes. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2020 STMicroelectronics. 11 | * All rights reserved.

12 | * 13 | * This software component is licensed by ST under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: 16 | * opensource.org/licenses/BSD-3-Clause 17 | * 18 | ****************************************************************************** 19 | */ 20 | /* USER CODE END Header */ 21 | 22 | /* Includes ------------------------------------------------------------------*/ 23 | #include "stm32f4xx_hal.h" 24 | /* USER CODE BEGIN Includes */ 25 | 26 | /* USER CODE END Includes */ 27 | 28 | /* Private typedef -----------------------------------------------------------*/ 29 | /* USER CODE BEGIN TD */ 30 | 31 | /* USER CODE END TD */ 32 | 33 | /* Private define ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN Define */ 35 | 36 | /* USER CODE END Define */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN Macro */ 40 | 41 | /* USER CODE END Macro */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | /* USER CODE BEGIN PV */ 45 | 46 | /* USER CODE END PV */ 47 | 48 | /* Private function prototypes -----------------------------------------------*/ 49 | /* USER CODE BEGIN PFP */ 50 | 51 | /* USER CODE END PFP */ 52 | 53 | /* External functions --------------------------------------------------------*/ 54 | /* USER CODE BEGIN ExternalFunctions */ 55 | 56 | /* USER CODE END ExternalFunctions */ 57 | 58 | /* USER CODE BEGIN 0 */ 59 | 60 | /* USER CODE END 0 */ 61 | /** 62 | * Initializes the Global MSP. 63 | */ 64 | void HAL_MspInit(void) 65 | { 66 | /* USER CODE BEGIN MspInit 0 */ 67 | 68 | /* USER CODE END MspInit 0 */ 69 | 70 | __HAL_RCC_SYSCFG_CLK_ENABLE(); 71 | __HAL_RCC_PWR_CLK_ENABLE(); 72 | 73 | /* System interrupt init*/ 74 | 75 | /* USER CODE BEGIN MspInit 1 */ 76 | 77 | /* USER CODE END MspInit 1 */ 78 | } 79 | 80 | /* USER CODE BEGIN 1 */ 81 | 82 | /* USER CODE END 1 */ 83 | 84 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 85 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/CK_USBD_BUFFER.c: -------------------------------------------------------------------------------- 1 | 2 | #include "stdint.h" // uint8_t type 3 | #include "stdlib.h" // malloc 4 | #include "string.h" // memcpy 5 | 6 | #include "USBD_CDC/CK_USBD_BUFFER.h" 7 | 8 | void CK_USBD_BUFFER_Init(circularBuffer_t* cb, int size){ 9 | 10 | cb->buffer = malloc(sizeof(uint8_t) * size); 11 | cb->head = 0; 12 | cb->tail = 0; 13 | cb->size = size; 14 | 15 | } 16 | 17 | int CK_USBD_BUFFER_BufferWrite(circularBuffer_t* c, uint8_t data){ 18 | 19 | // next is where head will point to after this write. 20 | int next = c->head + 1; 21 | if (next >= c->size) 22 | next = 0; //revolve to start location of buffer 23 | 24 | if (next == c->tail) // check if circular buffer is full 25 | return -1; // and return with an error. 26 | 27 | c->buffer[c->head] = data; // Load data and then move 28 | c->head = next; // head to next data offset. 29 | 30 | return 0; // return success to indicate successful push. 31 | } 32 | 33 | int CK_USBD_BUFFER_BufferWriteMulti(circularBuffer_t* c, uint8_t* buff, uint32_t length){ 34 | 35 | // When using this method the checking should be done outside 36 | // by using CK_CIRCULARBUFFER_GetAvailable. 37 | 38 | // The buff content is copied over circular buffer array. 39 | memcpy(c->buffer, buff, length); 40 | 41 | // Move head numberOfElement times since that much data is written at once. 42 | c->head += length; 43 | 44 | return 0; // return success to indicate successful push. 45 | 46 | } 47 | 48 | int CK_USBD_BUFFER_BufferRead(circularBuffer_t* c, uint8_t* data){ 49 | 50 | // if the head isn't ahead of the tail, we don't have any characters 51 | if (c->head == c->tail) // check if circular buffer is empty 52 | return -1; // and return with an error 53 | 54 | // next is where tail will point to after this read. 55 | int next = c->tail + 1; 56 | if(next >= c->size) 57 | next = 0; //revolve to start location of buffer 58 | 59 | *data = c->buffer[c->tail]; // Read data and then move 60 | c->tail = next; // tail to next data offset. 61 | 62 | return 0; // return success to indicate successful push. 63 | 64 | } 65 | 66 | /* 67 | * Get all elements in the buffer. 68 | */ 69 | void CK_USBD_BUFFER_GetBuffer(circularBuffer_t* c, uint8_t* buff, uint32_t* numOfElement){ 70 | 71 | uint32_t len = c->head - c->tail; 72 | *numOfElement = len; 73 | 74 | // The circular buffer content is copied over buf array. 75 | memcpy(buff, c->buffer, len); 76 | 77 | // Now since all the data is taken reset. 78 | c->head = 0; 79 | 80 | c->tail = 0; 81 | 82 | } 83 | 84 | /* 85 | * Return number of element available to write 86 | */ 87 | int CK_USBD_BUFFER_GetAvailable(circularBuffer_t* c){ 88 | 89 | return c->size - (c->head - c->tail); 90 | 91 | } 92 | 93 | bool CK_USBD_BUFFER_IsBufferEmpty(circularBuffer_t* c){ 94 | return c->head == c->tail; 95 | } 96 | 97 | bool CK_USBD_BUFFER_IsBufferFull(circularBuffer_t* c){ 98 | return ((c->head + 1) % c->size) == c->tail; 99 | } 100 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/sysmem.c: -------------------------------------------------------------------------------- 1 | /** 2 | ***************************************************************************** 3 | ** 4 | ** File : sysmem.c 5 | ** 6 | ** Author : Auto-generated by STM32CubeIDE 7 | ** 8 | ** Abstract : STM32CubeIDE Minimal System Memory calls file 9 | ** 10 | ** For more information about which c-functions 11 | ** need which of these lowlevel functions 12 | ** please consult the Newlib libc-manual 13 | ** 14 | ** Environment : STM32CubeIDE MCU 15 | ** 16 | ** Distribution: The file is distributed as is, without any warranty 17 | ** of any kind. 18 | ** 19 | ***************************************************************************** 20 | ** 21 | **

© COPYRIGHT(c) 2018 STMicroelectronics

22 | ** 23 | ** Redistribution and use in source and binary forms, with or without modification, 24 | ** are permitted provided that the following conditions are met: 25 | ** 1. Redistributions of source code must retain the above copyright notice, 26 | ** this list of conditions and the following disclaimer. 27 | ** 2. Redistributions in binary form must reproduce the above copyright notice, 28 | ** this list of conditions and the following disclaimer in the documentation 29 | ** and/or other materials provided with the distribution. 30 | ** 3. Neither the name of STMicroelectronics nor the names of its contributors 31 | ** may be used to endorse or promote products derived from this software 32 | ** without specific prior written permission. 33 | ** 34 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 35 | ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 | ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 37 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 38 | ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39 | ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 40 | ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 41 | ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 42 | ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 43 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | ** 45 | ** 46 | ***************************************************************************** 47 | */ 48 | 49 | /* Includes */ 50 | #include 51 | #include 52 | 53 | /* Variables */ 54 | extern int errno; 55 | register char * stack_ptr asm("sp"); 56 | 57 | /* Functions */ 58 | 59 | /** 60 | _sbrk 61 | Increase program data space. Malloc and related functions depend on this 62 | **/ 63 | caddr_t _sbrk(int incr) 64 | { 65 | extern char end asm("end"); 66 | static char *heap_end; 67 | char *prev_heap_end; 68 | 69 | if (heap_end == 0) 70 | heap_end = &end; 71 | 72 | prev_heap_end = heap_end; 73 | if (heap_end + incr > stack_ptr) 74 | { 75 | errno = ENOMEM; 76 | return (caddr_t) -1; 77 | } 78 | 79 | heap_end += incr; 80 | 81 | return (caddr_t) prev_heap_end; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /Radar RF/Radar RF: -------------------------------------------------------------------------------- 1 | 2 | +++++++++++++++ORDERED+++++++++++++++++ 3 | 4 | U2 ,1,"ADF4158","Footprints:LFCSP24_4x4mm_P0.5mm_1EXP_2.5x2.5mm","" 5 | 6 | U3 ,1,"SG-210STF","Footprints:Crystal_2.5x2mm","" 7 | 8 | U11 ,1,"HMC431LP4","Footprints:QFN24_4x4mm_P0.5mm_1EXP_2.7x2.7mm","" 9 | 10 | U16 ,1,"TQP5523","Footprints:QFN20_4x4mm_P0.5mm_1EXP_2.5x2.5mm","" 11 | 12 | U14 U19 ,2,"PAT1220-C-6DB","Footprints:PAT1220_6dB","" 13 | 14 | U10 ,1,"ADL5801","Footprints:LFCSP24_4x4mm_P0.5mm_1EXP_2.5x2.5mm","" 15 | 16 | U13 U6 ,2,"5400BL15B050E","Footprints:Balun_5400BL15B050E","" 17 | 18 | U18 ,1,"SKY65404","Footprints:SKY65404_31","" 19 | 20 | U15 ,1,"TRF37A73","Footprints:WSON8_2x2mm_P0.5mm_1EXP_0.9x1.6mm","" 21 | 22 | L3 ,1,"BLM18PG181SN1D","Footprints:SMD_0603","" 23 | 24 | L4 ,1,"LQW15AN9N9J80D","Footprints:SMD_0402","" 25 | 26 | U7 ,1,"TLV172","Footprints:SC70_5","" 27 | 28 | U1 ,1,"LT6232","Footprints:SSOP16_3.9x4.9mm_P0.635mm","" 29 | 30 | U12 ,1,"LDS3985","Footprints:SOT23_5","" 31 | 32 | U17 ,1,"MCP1700","Footprints:SOT23_3","" 33 | 34 | C70 ,1,"10uF","Footprints:SMD_0402","" 35 | 36 | L1 L2 ,2,"2.2uH","Footprints:SMD_0603","" 37 | 38 | L5 ,1,"0.6nH","Footprints:SMD_0402","" 39 | 40 | J1 ,1,"Connector_02x15","Footprints:PinHeader_2x15_DF12B(5.0)-30DP-0.5V(86)","" 41 | 42 | C49 C57 C63 C71 ,4,"2.2uF","Footprints:SMD_0402","" 43 | 44 | C68 C59 C15 C16 C18 ,5,"18pF","Footprints:SMD_0402","" 45 | 46 | C17 ,1,"2.2nF","Footprints:SMD_0402","" 47 | 48 | C26 C19 C20 ,3,"330nF","Footprints:SMD_0402","" 49 | 50 | C27 ,1,"2pF","Footprints:SMD_0402","" 51 | 52 | C62 C54 C55 C35 C36 C24 C25 ,7,"10pF","Footprints:SMD_0402","" 53 | 54 | C73 ,1,"0.5pF","Footprints:SMD_0402","" 55 | 56 | C60 C72 ,2,"1000pF","Footprints:SMD_0402","" 57 | 58 | ***C37 C13 C14 C12 C21 C51 C64 C67 C69 C74 C75 C52 C39 C38 C40 C48 C43 C46 C50 C45 C22 C28 C53 ,23,"100nF","Footprints:SMD_0402","" VAR 59 | 60 | ***C30 C61 C56 ,3,"10nF","Footprints:SMD_0402","" VAR 61 | 62 | ***C23 C65 C42 C41 C47 ,5,"100pF","Footprints:SMD_0402","" VAR 63 | 64 | ***R15 C66 C58 R27 R30 ,5,"DNP","Footprints:SMD_0402","" 65 | 66 | ***R38 ,1,"100","Footprints:SMD_0402","" VAR 67 | 68 | ***R9 R10 R34 ,3,"10K","Footprints:SMD_0402","" VAR 69 | 70 | ***D1 D2 D3 ,3,"Led_Diode","Footprints:Diode_0603","" VAR 71 | 72 | ***R22 R12 R35 ,3,"0","Footprints:SMD_0402","" VAR 73 | 74 | ***R24 R23 R26 ,3,"4.7K","Footprints:SMD_0402","" VAR 75 | 76 | ***R29 R16 R19 R39 R40 R42 R1 ,7,"1K","Footprints:SMD_0402","" VAR 77 | 78 | C44 C29 C31 C32 C33 C34 ,6,"470pF","Footprints:SMD_0402","" 79 | 80 | R8 ,1,"69.8","Footprints:SMD_0402","" 81 | 82 | R11 ,1,"240","Footprints:SMD_0402","" 83 | 84 | R13 R14 ,2,"910","Footprints:SMD_0402","" 85 | 86 | R6 R5 ,2,"549","Footprints:SMD_0402","" 87 | 88 | R7 ,1,"5.49K","Footprints:SMD_0402","" 89 | 90 | R37 ,1,"30K","Footprints:SMD_0402","" 91 | 92 | R20 R21 ,2,"4.99K","Footprints:SMD_0402","" 93 | 94 | R18 R17 ,2,"130","Footprints:SMD_0402","" 95 | 96 | R41 R25 R28 ,3,"50","Footprints:SMD_0402","" 97 | 98 | R31 R32 R33 ,3,"18","Footprints:SMD_0402","" 99 | 100 | ***R36 ,1,"0 to 27","Footprints:SMD_0402","" 10 ohm ve 0 ohm var 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_MCP4022.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_MCP4022.h" 3 | #include "CK_GPIO.h" 4 | #include "CK_TIME_HAL.h" 5 | 6 | #define MCP4022_GPIO GPIOC 7 | #define MCP4022_CS_PIN 2 8 | #define MCP4022_UD_PIN 3 9 | 10 | #define MCP4022_MAXVALUE 0x3F 11 | 12 | uint8_t current_value = 0; 13 | 14 | void MCP4022_Init(void){ 15 | 16 | // MCP4022 has 64 resistor levels in it which can be incremented or decremented 17 | // with CS pin is pulled low and sending 0x00 to 0x3F values with UD pin 18 | // to select one resistor level. 19 | 20 | CK_GPIO_Init(MCP4022_GPIO, MCP4022_UD_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_HIGH, CK_GPIO_NOPUPD); 21 | MCP4022_UD_Low(); 22 | 23 | CK_GPIO_Init(MCP4022_GPIO, MCP4022_CS_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_HIGH, CK_GPIO_NOPUPD); 24 | MCP4022_CS_Low(); 25 | 26 | } 27 | 28 | // Because of NPN transistor when send high it will be connected to GND 29 | // and will be high when send 3v3 30 | void MCP4022_UD_High(void){ 31 | CK_GPIO_ClearPin(MCP4022_GPIO, MCP4022_UD_PIN); 32 | } 33 | 34 | void MCP4022_UD_Low(void){ 35 | CK_GPIO_SetPin(MCP4022_GPIO, MCP4022_UD_PIN); 36 | } 37 | 38 | void MCP4022_CS_High(void){ 39 | CK_GPIO_ClearPin(MCP4022_GPIO, MCP4022_CS_PIN); 40 | } 41 | 42 | void MCP4022_CS_Low(void){ 43 | CK_GPIO_SetPin(MCP4022_GPIO, MCP4022_CS_PIN); 44 | } 45 | 46 | void MCP4022_SetValue(uint8_t new_value){ 47 | 48 | // Device has 64 steps new value is hex value max 0x3F = 63 49 | // Rwb = (Rab * new_value) / 63; 50 | 51 | if(new_value > MCP4022_MAXVALUE){ 52 | new_value = MCP4022_MAXVALUE; 53 | } 54 | 55 | uint8_t val = 0; 56 | if(new_value > current_value){ 57 | val = new_value - current_value; 58 | MCP4022_Increase(val); 59 | } 60 | else if(new_value < current_value){ 61 | val = current_value - new_value; 62 | MCP4022_Decrease(val); 63 | } 64 | 65 | } 66 | 67 | void MCP4022_Increase(uint8_t value){ 68 | 69 | // Increment mode UD high prior to CS low 70 | // Every subsequent rising edge increments one value 71 | // Min value of pot. is 0x00 max is 0x3F 72 | // Incremented value is not written to EEPROM in this config. 73 | // To write it to EEPROM, during connection UD pull Low and force CS high. (not used now) 74 | // If reaches 0x3F it ignores new increments. 75 | 76 | MCP4022_UD_High(); 77 | MCP4022_CS_Low(); 78 | CK_TIME_DelayMicroSec(5); 79 | 80 | for(int i = 0; i < value; i++){ 81 | MCP4022_UD_Low(); 82 | CK_TIME_DelayMicroSec(3); 83 | MCP4022_UD_High(); 84 | CK_TIME_DelayMicroSec(3); 85 | } 86 | 87 | CK_TIME_DelayMicroSec(5); 88 | MCP4022_UD_High(); 89 | MCP4022_CS_High(); 90 | 91 | } 92 | 93 | void MCP4022_Decrease(uint8_t value){ 94 | 95 | // Decrement mode UD low prior to CS low 96 | // Every subsequent rising edge decrements one value 97 | 98 | MCP4022_UD_Low(); 99 | MCP4022_CS_Low(); 100 | CK_TIME_DelayMicroSec(5); 101 | 102 | for(int i = 0; i < value; i++){ 103 | MCP4022_UD_High(); 104 | CK_TIME_DelayMicroSec(3); 105 | MCP4022_UD_Low(); 106 | CK_TIME_DelayMicroSec(3); 107 | } 108 | 109 | CK_TIME_DelayMicroSec(5); 110 | MCP4022_UD_High(); 111 | MCP4022_CS_High(); 112 | 113 | } 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_ioreq.c: -------------------------------------------------------------------------------- 1 | 2 | #include "USBD_CDC/usbd_ioreq.h" 3 | 4 | /** 5 | * @brief USBD_CtlSendData 6 | * send data on the ctl pipe 7 | * @param pdev: device instance 8 | * @param buff: pointer to data buffer 9 | * @param len: length of data to be sent 10 | * @retval status 11 | */ 12 | USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, uint8_t *pbuf, 13 | uint16_t len) 14 | { 15 | /* Set EP0 State */ 16 | pdev->ep0_state = USBD_EP0_DATA_IN; 17 | pdev->ep_in[0].total_length = len; 18 | pdev->ep_in[0].rem_length = len; 19 | 20 | /* Start the transfer */ 21 | USBD_LL_Transmit (pdev, 0x00U, pbuf, len); 22 | 23 | return USBD_OK; 24 | } 25 | 26 | /** 27 | * @brief USBD_CtlContinueSendData 28 | * continue sending data on the ctl pipe 29 | * @param pdev: device instance 30 | * @param buff: pointer to data buffer 31 | * @param len: length of data to be sent 32 | * @retval status 33 | */ 34 | USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, 35 | uint8_t *pbuf, uint16_t len) 36 | { 37 | /* Start the next transfer */ 38 | USBD_LL_Transmit (pdev, 0x00U, pbuf, len); 39 | 40 | return USBD_OK; 41 | } 42 | 43 | /** 44 | * @brief USBD_CtlPrepareRx 45 | * receive data on the ctl pipe 46 | * @param pdev: device instance 47 | * @param buff: pointer to data buffer 48 | * @param len: length of data to be received 49 | * @retval status 50 | */ 51 | USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev, uint8_t *pbuf, 52 | uint16_t len) 53 | { 54 | /* Set EP0 State */ 55 | pdev->ep0_state = USBD_EP0_DATA_OUT; 56 | pdev->ep_out[0].total_length = len; 57 | pdev->ep_out[0].rem_length = len; 58 | 59 | /* Start the transfer */ 60 | USBD_LL_PrepareReceive (pdev, 0U, pbuf, len); 61 | 62 | return USBD_OK; 63 | } 64 | 65 | /** 66 | * @brief USBD_CtlContinueRx 67 | * continue receive data on the ctl pipe 68 | * @param pdev: device instance 69 | * @param buff: pointer to data buffer 70 | * @param len: length of data to be received 71 | * @retval status 72 | */ 73 | USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, uint8_t *pbuf, 74 | uint16_t len) 75 | { 76 | USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); 77 | 78 | return USBD_OK; 79 | } 80 | 81 | /** 82 | * @brief USBD_CtlSendStatus 83 | * send zero lzngth packet on the ctl pipe 84 | * @param pdev: device instance 85 | * @retval status 86 | */ 87 | USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev) 88 | { 89 | /* Set EP0 State */ 90 | pdev->ep0_state = USBD_EP0_STATUS_IN; 91 | 92 | /* Start the transfer */ 93 | USBD_LL_Transmit(pdev, 0x00U, NULL, 0U); 94 | 95 | return USBD_OK; 96 | } 97 | 98 | /** 99 | * @brief USBD_CtlReceiveStatus 100 | * receive zero lzngth packet on the ctl pipe 101 | * @param pdev: device instance 102 | * @retval status 103 | */ 104 | USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev) 105 | { 106 | /* Set EP0 State */ 107 | pdev->ep0_state = USBD_EP0_STATUS_OUT; 108 | 109 | /* Start the transfer */ 110 | USBD_LL_PrepareReceive (pdev, 0U, NULL, 0U); 111 | 112 | return USBD_OK; 113 | } 114 | 115 | /** 116 | * @brief USBD_GetRxCount 117 | * returns the received data length 118 | * @param pdev: device instance 119 | * @param ep_addr: endpoint address 120 | * @retval Rx Data blength 121 | */ 122 | uint32_t USBD_GetRxCount (USBD_HandleTypeDef *pdev, uint8_t ep_addr) 123 | { 124 | return USBD_LL_GetRxDataSize(pdev, ep_addr); 125 | } 126 | 127 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_core.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __USBD_CORE_H 3 | #define __USBD_CORE_H 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | /* Includes ------------------------------------------------------------------*/ 10 | #include "USBD_CDC/usbd_conf.h" 11 | #include "USBD_CDC/usbd_def.h" 12 | #include "USBD_CDC/usbd_ioreq.h" 13 | #include "USBD_CDC/usbd_ctlreq.h" 14 | 15 | #ifndef USBD_DEBUG_LEVEL 16 | #define USBD_DEBUG_LEVEL 0U 17 | #endif /* USBD_DEBUG_LEVEL */ 18 | 19 | #define USBD_SOF USBD_LL_SOF 20 | 21 | USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id); 22 | USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); 23 | USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev); 24 | USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev); 25 | USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); 26 | 27 | USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev); 28 | USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); 29 | USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); 30 | 31 | USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup); 32 | USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata); 33 | USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata); 34 | 35 | USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); 36 | USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); 37 | USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); 38 | USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); 39 | 40 | USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev); 41 | USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); 42 | USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); 43 | 44 | USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); 45 | USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); 46 | 47 | /* USBD Low Level Driver */ 48 | USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev); 49 | USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev); 50 | USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); 51 | USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev); 52 | USBD_StatusTypeDef USBD_LL_OpenEP (USBD_HandleTypeDef *pdev, 53 | uint8_t ep_addr, 54 | uint8_t ep_type, 55 | uint16_t ep_mps); 56 | 57 | USBD_StatusTypeDef USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); 58 | USBD_StatusTypeDef USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); 59 | USBD_StatusTypeDef USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); 60 | USBD_StatusTypeDef USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); 61 | uint8_t USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); 62 | USBD_StatusTypeDef USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr); 63 | USBD_StatusTypeDef USBD_LL_Transmit (USBD_HandleTypeDef *pdev, 64 | uint8_t ep_addr, 65 | uint8_t *pbuf, 66 | uint16_t size); 67 | 68 | USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, 69 | uint8_t ep_addr, 70 | uint8_t *pbuf, 71 | uint16_t size); 72 | 73 | uint32_t USBD_LL_GetRxDataSize (USBD_HandleTypeDef *pdev, uint8_t ep_addr); 74 | void USBD_LL_Delay (uint32_t Delay); 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_cdc.h: -------------------------------------------------------------------------------- 1 | 2 | /* Define to prevent recursive inclusion -------------------------------------*/ 3 | #ifndef __USB_CDC_H 4 | #define __USB_CDC_H 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /* Includes ------------------------------------------------------------------*/ 11 | #include "USBD_CDC/usbd_ioreq.h" 12 | 13 | #define CDC_IN_EP 0x81U /* EP1 for data IN */ 14 | #define CDC_OUT_EP 0x01U /* EP1 for data OUT */ 15 | #define CDC_CMD_EP 0x82U /* EP2 for CDC commands */ 16 | 17 | #ifndef CDC_HS_BINTERVAL 18 | #define CDC_HS_BINTERVAL 0x10U 19 | #endif /* CDC_HS_BINTERVAL */ 20 | 21 | #ifndef CDC_FS_BINTERVAL 22 | #define CDC_FS_BINTERVAL 0x10U 23 | #endif /* CDC_FS_BINTERVAL */ 24 | 25 | /* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ 26 | #define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ 27 | #define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ 28 | 29 | #define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ 30 | 31 | #define USB_CDC_CONFIG_DESC_SIZ 67U 32 | #define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE 33 | #define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE 34 | 35 | #define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE 36 | #define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE 37 | 38 | /*---------------------------------------------------------------------*/ 39 | /* CDC definitions */ 40 | /*---------------------------------------------------------------------*/ 41 | #define CDC_SEND_ENCAPSULATED_COMMAND 0x00U 42 | #define CDC_GET_ENCAPSULATED_RESPONSE 0x01U 43 | #define CDC_SET_COMM_FEATURE 0x02U 44 | #define CDC_GET_COMM_FEATURE 0x03U 45 | #define CDC_CLEAR_COMM_FEATURE 0x04U 46 | #define CDC_SET_LINE_CODING 0x20U 47 | #define CDC_GET_LINE_CODING 0x21U 48 | #define CDC_SET_CONTROL_LINE_STATE 0x22U 49 | #define CDC_SEND_BREAK 0x23U 50 | 51 | typedef struct 52 | { 53 | uint32_t bitrate; 54 | uint8_t format; 55 | uint8_t paritytype; 56 | uint8_t datatype; 57 | }USBD_CDC_LineCodingTypeDef; 58 | 59 | typedef struct _USBD_CDC_Itf 60 | { 61 | int8_t (* Init) (void); 62 | int8_t (* DeInit) (void); 63 | int8_t (* Control) (uint8_t cmd, uint8_t* pbuf, uint16_t length); 64 | int8_t (* Receive) (uint8_t* Buf, uint32_t *Len); 65 | 66 | }USBD_CDC_ItfTypeDef; 67 | 68 | 69 | typedef struct 70 | { 71 | uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */ 72 | uint8_t CmdOpCode; 73 | uint8_t CmdLength; 74 | uint8_t *RxBuffer; 75 | uint8_t *TxBuffer; 76 | uint32_t RxLength; 77 | uint32_t TxLength; 78 | 79 | __IO uint32_t TxState; 80 | __IO uint32_t RxState; 81 | } 82 | USBD_CDC_HandleTypeDef; 83 | 84 | extern USBD_ClassTypeDef USBD_CDC; 85 | #define USBD_CDC_CLASS &USBD_CDC 86 | 87 | /** @defgroup USB_CORE_Exported_Functions 88 | * @{ 89 | */ 90 | uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, 91 | USBD_CDC_ItfTypeDef *fops); 92 | 93 | uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, 94 | uint8_t *pbuff, 95 | uint16_t length); 96 | 97 | uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, 98 | uint8_t *pbuff); 99 | 100 | uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev); 101 | 102 | uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev); 103 | 104 | 105 | #ifdef __cplusplus 106 | } 107 | #endif 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /Radar 2/Radar v2: -------------------------------------------------------------------------------- 1 | Reference, Quantity, Value, Footprint, Datasheet 2 | C105 C106 C108 C104 ,4,"2.2uF","Footprints:SMD_0603","" 3 | C14 C15 C11 C6 C21 C69 ,6,"2.2uF","Footprints:SMD_0402","" 4 | C16 C17 ,2,"15pF","Footprints:SMD_0402","" 5 | C18 C19 ,2,"1uF","Footprints:SMD_0402","" 6 | C20 C3 C4 C2 C23 C28 C22 C27 C29 C26 C31 C30 C10 C7 C8 C1 C59 C35 C36 C109 C46 C70 C85 C87 C88 C84 C86 C80 C58 C43 C41 C44 C110 C49 C51 C56 C50 C32 C66 C101 C100 ,41,"100nF","Footprints:SMD_0402","" 7 | C25 C24 C48 C79 C47 C45 C53 ,7,"100pF","Footprints:SMD_0402","" 8 | C33 C73 C74 C77 C78 ,5,"470pF","Footprints:SMD_0402","" 9 | C37 C38 C42 ,3,"18pF","Footprints:SMD_0402","" 10 | C5 C12 C89 C91 C98 C92 C99 C96 C95 C97 ,10,"10uF","Footprints:SMD_0603","" 11 | C52 ,1,"2pF","Footprints:SMD_0402","" 12 | C55 C62 ,2,"2.2nF","Footprints:SMD_0402","" 13 | C57 ,1,"51pF","Footprints:SMD_0402","" 14 | C63 C64 ,2,"330nF","Footprints:SMD_0402","" 15 | C65 ,1,"68pF","Footprints:SMD_0402","" 16 | C75 C103 C93 C94 C107 C102 ,6,"10nF","Footprints:SMD_0402","" 17 | C76 C60 C61 C39 C40 C67 C68 ,7,"10pF","Footprints:SMD_0402","" 18 | C82 C90 C81 C72 ,4,"1nF","Footprints:SMD_0402","" 19 | C83 ,1,"0.5pF","Footprints:SMD_0402","" 20 | C9 C13 ,2,"33pF","Footprints:SMD_0402","" 21 | D1 D2 ,2,"Diode_Schottky","Footprints:Diode_SDM2U30CSP_7","" 22 | D9 D10 D4 D3 D5 D7 D6 D8 ,8,"Led_Diode","Footprints:Diode_0603","" 23 | F1 ,1,"Fuse","Footprints:SMD_0805","" 24 | J1 ,1,"Connector_01x04","Footprints:PinHeader_1x4_P2.54mm","" 25 | J2 ,1,"USB_MicroB","Footprints:USB_MicroB_TH","" 26 | J3 ,1,"SWD_DEBUGGER","Footprints:PinHeader_1x5_P2.54mm","" 27 | J4 ,1,"DC_Jack","Footprints:BarrelJack","" 28 | L10 L11 ,2,"4.7uH","Footprints:SMD_0805","" 29 | L2 L3 ,2,"2.2uH","Footprints:SMD_0603","" 30 | L5 L1 L4 L8 L9 ,5,"BLM18PG181SN1D","Footprints:SMD_0603","" 31 | L6 ,1,"LQW18ANR10J00D","Footprints:SMD_0402","" 32 | L7 ,1,"0.6nH","Footprints:SMD_0402","" 33 | Q2 Q1 ,2,"BSS138","Footprints:SOT23_3","" 34 | R10 R18 R21 R22 R3 R4 R41 R42 R65 R61 R64 ,11,"10K","Footprints:SMD_0402","" 35 | R14 ,1,"49.9","Footprints:SMD_0402","" 36 | R16 R1 R2 R76 ,4,"100","Footprints:SMD_0402","" 37 | R19 R17 R37 R36 R38 R63 ,6,"4.7K","Footprints:SMD_0402","" 38 | R20 R7 R8 R13 R30 R46 R49 R56 R79 R80 R67 R66 R68 R70 R69 R71 ,16,"1K","Footprints:SMD_0402","" 39 | R23 R15 R72 R73 R28 R75 C71 R27 R31 ,9,"DNP","Footprints:SMD_0402","" 40 | R24 R35 R33 ,3,"0","Footprints:SMD_0402","" 41 | R26 ,1,"5.49K","Footprints:SMD_0402","" 42 | R32 ,1,"3.1K","Footprints:SMD_0402","" 43 | R40 R39 ,2,"549","Footprints:SMD_0402","" 44 | R43 ,1,"1.8","Footprints:SMD_0402","" 45 | R44 R45 ,2,"910","Footprints:SMD_0402","" 46 | R48 R47 ,2,"130","Footprints:SMD_0402","" 47 | R5 R6 R12 R74 ,4,"22","Footprints:SMD_0402","" 48 | R50 R51 ,2,"4.99K","Footprints:SMD_0402","" 49 | R52 R77 R78 ,3,"16.7","Footprints:SMD_0402","" 50 | R57 ,1,"0 to 27","Footprints:SMD_0402","" 51 | R58 ,1,"30K","Footprints:SMD_0402","" 52 | R59 R25 R29 ,3,"50","Footprints:SMD_0402","" 53 | R60 ,1,"51.4K","Footprints:SMD_0402","" 54 | R62 ,1,"14.7K","Footprints:SMD_0402","" 55 | R9 R11 ,2,"2.49K","Footprints:SMD_0402","" 56 | SW1 ,1,"DFU_Button","Footprints:Button_B3U_1000P","" 57 | SW2 ,1,"Reset_Button","Footprints:Button_B3U_1000P","" 58 | U1 ,1,"MCP4022","Footprints:SOT23_6","" 59 | U12 ,1,"TLV172","Footprints:SC70_5","" 60 | U13 U7 ,2,"5400BL15B050E","Footprints:Balun_5400BL15B050E","" 61 | U15 ,1,"LT6232","Footprints:SSOP16_3.9x4.9mm_P0.635mm","" 62 | U17 ,1,"HMC431LP4","Footprints:QFN24_4x4mm_P0.5mm_1EXP_2.7x2.7mm","" 63 | U18 ,1,"TRF37A75","Footprints:WSON8_2x2mm_P0.5mm_1EXP_0.9x1.6mm","" 64 | U19 U27 ,2,"PAT1220-C-6DB","Footprints:PAT1220_6dB","" 65 | U2 ,1,"LT1817GN","Footprints:SSOP16_3.9x4.9mm_P0.635mm","" 66 | U20 ,1,"SKY65404","Footprints:SKY65404_31","" 67 | U21 ,1,"TQP5523","Footprints:QFN20_4x4mm_P0.5mm_1EXP_2.5x2.5mm","" 68 | U28 U23 U42 U44 U43 ,5,"MITERED_BEND","Footprints:Mitered_Bend_0.33mm_90","" 69 | U29 ,1,"Directional_Coupler","Footprints:Directional_Coupler_15dB","" 70 | U3 U39 U40 U41 U11 U10 U24 U14 U36 ,9,"Check_Point","Footprints:SolderPad_1_1.5mm_SMD_Circle","" 71 | U30 U22 ,2,"SMA_Connector","Footprints:SMA_Connector","" 72 | U31 U32 ,2,"AP3211","Footprints:SOT23_6","" 73 | U35 ,1,"LP298XS","Footprints:SOT23_5","" 74 | U37 ,1,"MicroCard","Footprints:MICROCARD_DM3AT_SF_PEJM5","" 75 | U38 U33 ,2,"LDS3985","Footprints:SOT23_5","" 76 | U4 ,1,"STM32F405","Footprints:LQFP64_10x10mm_P0.5mm","" 77 | U6 ,1,"SG-210STF","Footprints:Crystal_2.5x2mm","" 78 | U8 ,1,"ADF4158","Footprints:LFCSP24_4x4mm_P0.5mm_1EXP_2.5x2.5mm","" 79 | U9 ,1,"ADL5801","Footprints:LFCSP24_4x4mm_P0.5mm_1EXP_2.5x2.5mm","" 80 | U99 ,1,"MAX1426","Footprints:SSOP28_5.3x10.2mm_P0.65mm","" 81 | Y1 ,1,"8MHz","Footprints:Crystal_3.2x2.5mm","" -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_TIME_HAL.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_SYSTEM.h" 3 | #include "CK_TIME_HAL.h" 4 | 5 | #define USE_HAL 1 6 | 7 | #define USE_DWT 0 8 | 9 | /* 10 | * 11 | * VERY VERY IMPORTANT: 12 | * 13 | * USE DWT only for debugging when it is activated 14 | * because after debugger disconnected code does not start. 15 | * When debugging i mean to see how much microsecond a method is taking precisely enable USE DWT 16 | * When code will be used on system comment it and use systick. 17 | */ 18 | 19 | #define CK_SYSTICK_CTRL_ENABLE 1u << 0 20 | #define CK_SYSTICK_CTRL_INT 1u << 1 21 | #define CK_SYSTICK_CTRL_CLKSOURCE 1u << 2 22 | #define CK_SYSTICK_LOAD_MASK 0xFFFFFFu 23 | 24 | int isFirst = 1; 25 | 26 | uint32_t sysTickCounter = 0; 27 | 28 | uint32_t timeout_num; 29 | 30 | void CK_TIME_SetTimeOut(uint32_t time){ 31 | 32 | timeout_num = time; 33 | 34 | } 35 | 36 | uint32_t CK_TIME_GetTimeOut(void){ 37 | 38 | return timeout_num; 39 | 40 | } 41 | 42 | // Overwrite of weak HAL decleration 43 | void HAL_IncTick(void){ 44 | 45 | sysTickCounter++; 46 | 47 | if(timeout_num > 0){ 48 | 49 | timeout_num--; 50 | 51 | } 52 | 53 | } 54 | 55 | // Overwrite of weak HAL decleration 56 | uint32_t HAL_GetTick(void){ 57 | 58 | return sysTickCounter ; 59 | 60 | } 61 | 62 | uint32_t CK_TIME_GetMicroSec_SYSTICK(void){ 63 | 64 | #if !USE_HAL 65 | 66 | //HAL Initialises This Part 67 | 68 | if(isFirst == 1){ 69 | 70 | isFirst = 0; 71 | 72 | SysTick->LOAD = ((uint32_t)((F_CPU/1000)-1)); // 1mS 73 | 74 | SysTick->VAL = 0; 75 | 76 | SysTick->CTRL |= CK_SYSTICK_CTRL_ENABLE | CK_SYSTICK_CTRL_INT | CK_SYSTICK_CTRL_CLKSOURCE; 77 | 78 | } 79 | 80 | #endif 81 | 82 | uint32_t ticks ; 83 | uint32_t count ; 84 | 85 | SysTick->CTRL; 86 | 87 | do{ 88 | ticks = SysTick->VAL; 89 | 90 | count = sysTickCounter; 91 | } 92 | while (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk); 93 | 94 | // Sometimes when this method called consequtively 95 | // it returns smaller compared to the previous call 96 | // and negative number is results too big result like 4988339 so ignore those values. 97 | 98 | return count * 1000 + (SysTick->LOAD + 1 - ticks) / (F_CPU / 1000000); 99 | 100 | 101 | } 102 | 103 | uint32_t CK_TIME_GetMilliSec_SYSTICK(void){ 104 | 105 | #if !USE_HAL 106 | 107 | //HAL Initialises This Part 108 | 109 | if(isFirst == 1){ 110 | 111 | isFirst = 0; 112 | 113 | SysTick->LOAD = ((uint32_t)((F_CPU/1000)-1)); // 1mS 114 | 115 | SysTick->VAL = 0; 116 | 117 | SysTick->CTRL |= CK_SYSTICK_CTRL_ENABLE | CK_SYSTICK_CTRL_INT | CK_SYSTICK_CTRL_CLKSOURCE; 118 | 119 | } 120 | 121 | #endif 122 | 123 | return sysTickCounter; 124 | } 125 | 126 | // DWT measures more precisely 127 | uint32_t CK_TIME_GetMicroSec_DWT(void){ 128 | 129 | // DWT counts the number of cpu clock passed so it is precise. 130 | // Systick sometimes returns smaller number between 2 consequtive calls 131 | // I added some logic to prevent returning smaller number than the previous 132 | // read but DWT can now be used. 133 | 134 | static int firstconfig = 0; 135 | static uint8_t clock_ = 0; 136 | 137 | if(firstconfig == 0){ 138 | firstconfig = 1; 139 | clock_ = (F_CPU / 1000000); 140 | 141 | DWT->CTRL |= 1 ; // enable the counter 142 | DWT->CYCCNT = 0; // reset the counter 143 | } 144 | 145 | // DWT counter rounds up after around 15 seconds. 146 | // so only one value at each 15th second could be wrong. 147 | uint32_t counter = DWT->CYCCNT / clock_; 148 | return counter; 149 | } 150 | 151 | uint32_t CK_TIME_GetMilliSec_DWT(void){ 152 | 153 | static int firstconfig = 0; 154 | static uint8_t clock_ = 0; 155 | 156 | if(firstconfig == 0){ 157 | firstconfig = 1; 158 | clock_ = (F_CPU / 1000000); 159 | 160 | DWT->CTRL |= 1 ; // enable the counter 161 | DWT->CYCCNT = 0; // reset the counter 162 | } 163 | 164 | // DWT counter rounds up after around 15 seconds. 165 | // so only one value at each 15th second could be wrong. 166 | uint32_t counter = DWT->CYCCNT / clock_; 167 | return counter / 1000; 168 | } 169 | 170 | uint32_t CK_TIME_GetMicroSec(void){ 171 | 172 | #if USE_DWT && !USE_HAL 173 | return CK_TIME_GetMicroSec_DWT(); 174 | #else 175 | return CK_TIME_GetMicroSec_SYSTICK(); 176 | #endif 177 | 178 | } 179 | 180 | uint32_t CK_TIME_GetMilliSec(void){ 181 | 182 | #if USE_DWT && !USE_HAL 183 | return CK_TIME_GetMilliSec_DWT(); 184 | #else 185 | return CK_TIME_GetMilliSec_SYSTICK(); 186 | #endif 187 | 188 | } 189 | 190 | void CK_TIME_DelayMilliSec(uint32_t msec){ 191 | 192 | while(msec--)CK_TIME_DelayMicroSec(1000); 193 | 194 | } 195 | 196 | void CK_TIME_DelayMicroSec(uint32_t usec){ 197 | 198 | uint32_t now = CK_TIME_GetMicroSec(); 199 | 200 | while (CK_TIME_GetMicroSec() - now < usec); 201 | 202 | } 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/syscalls.c: -------------------------------------------------------------------------------- 1 | /** 2 | ***************************************************************************** 3 | ** 4 | ** File : syscalls.c 5 | ** 6 | ** Author : Auto-generated by STM32CubeIDE 7 | ** 8 | ** Abstract : STM32CubeIDE Minimal System calls file 9 | ** 10 | ** For more information about which c-functions 11 | ** need which of these lowlevel functions 12 | ** please consult the Newlib libc-manual 13 | ** 14 | ** Environment : STM32CubeIDE MCU 15 | ** 16 | ** Distribution: The file is distributed as is, without any warranty 17 | ** of any kind. 18 | ** 19 | ***************************************************************************** 20 | ** 21 | **

© COPYRIGHT(c) 2018 STMicroelectronics

22 | ** 23 | ** Redistribution and use in source and binary forms, with or without modification, 24 | ** are permitted provided that the following conditions are met: 25 | ** 1. Redistributions of source code must retain the above copyright notice, 26 | ** this list of conditions and the following disclaimer. 27 | ** 2. Redistributions in binary form must reproduce the above copyright notice, 28 | ** this list of conditions and the following disclaimer in the documentation 29 | ** and/or other materials provided with the distribution. 30 | ** 3. Neither the name of STMicroelectronics nor the names of its contributors 31 | ** may be used to endorse or promote products derived from this software 32 | ** without specific prior written permission. 33 | ** 34 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 35 | ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 | ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 37 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 38 | ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39 | ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 40 | ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 41 | ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 42 | ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 43 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | ** 45 | ** 46 | ***************************************************************************** 47 | */ 48 | 49 | /* Includes */ 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | 60 | /* Variables */ 61 | //#undef errno 62 | extern int errno; 63 | extern int __io_putchar(int ch) __attribute__((weak)); 64 | extern int __io_getchar(void) __attribute__((weak)); 65 | 66 | register char * stack_ptr asm("sp"); 67 | 68 | char *__env[1] = { 0 }; 69 | char **environ = __env; 70 | 71 | 72 | /* Functions */ 73 | void initialise_monitor_handles() 74 | { 75 | } 76 | 77 | int _getpid(void) 78 | { 79 | return 1; 80 | } 81 | 82 | int _kill(int pid, int sig) 83 | { 84 | errno = EINVAL; 85 | return -1; 86 | } 87 | 88 | void _exit (int status) 89 | { 90 | _kill(status, -1); 91 | while (1) {} /* Make sure we hang here */ 92 | } 93 | 94 | __attribute__((weak)) int _read(int file, char *ptr, int len) 95 | { 96 | int DataIdx; 97 | 98 | for (DataIdx = 0; DataIdx < len; DataIdx++) 99 | { 100 | *ptr++ = __io_getchar(); 101 | } 102 | 103 | return len; 104 | } 105 | 106 | __attribute__((weak)) int _write(int file, char *ptr, int len) 107 | { 108 | int DataIdx; 109 | 110 | for (DataIdx = 0; DataIdx < len; DataIdx++) 111 | { 112 | __io_putchar(*ptr++); 113 | } 114 | return len; 115 | } 116 | 117 | int _close(int file) 118 | { 119 | return -1; 120 | } 121 | 122 | 123 | int _fstat(int file, struct stat *st) 124 | { 125 | st->st_mode = S_IFCHR; 126 | return 0; 127 | } 128 | 129 | int _isatty(int file) 130 | { 131 | return 1; 132 | } 133 | 134 | int _lseek(int file, int ptr, int dir) 135 | { 136 | return 0; 137 | } 138 | 139 | int _open(char *path, int flags, ...) 140 | { 141 | /* Pretend like we always fail */ 142 | return -1; 143 | } 144 | 145 | int _wait(int *status) 146 | { 147 | errno = ECHILD; 148 | return -1; 149 | } 150 | 151 | int _unlink(char *name) 152 | { 153 | errno = ENOENT; 154 | return -1; 155 | } 156 | 157 | int _times(struct tms *buf) 158 | { 159 | return -1; 160 | } 161 | 162 | int _stat(char *file, struct stat *st) 163 | { 164 | st->st_mode = S_IFCHR; 165 | return 0; 166 | } 167 | 168 | int _link(char *old, char *new) 169 | { 170 | errno = EMLINK; 171 | return -1; 172 | } 173 | 174 | int _fork(void) 175 | { 176 | errno = EAGAIN; 177 | return -1; 178 | } 179 | 180 | int _execve(char *name, char **argv, char **env) 181 | { 182 | errno = ENOMEM; 183 | return -1; 184 | } 185 | -------------------------------------------------------------------------------- /Radar RF/Radar RF.pro: -------------------------------------------------------------------------------- 1 | update=2019 November 14, Thursday 18:54:44 2 | last_client=kicad 3 | [general] 4 | version=1 5 | [schematic_editor] 6 | version=1 7 | PageLayoutDescrFile= 8 | PlotDirectoryName= 9 | SubpartIdSeparator=0 10 | SubpartFirstId=65 11 | NetFmtName=Pcbnew 12 | SpiceAjustPassiveValues=0 13 | LabSize=50 14 | ERC_TestSimilarLabels=1 15 | [pcbnew] 16 | version=1 17 | PageLayoutDescrFile= 18 | LastNetListRead=Radar RF.net 19 | CopperLayerCount=4 20 | BoardThickness=1.6 21 | AllowMicroVias=0 22 | AllowBlindVias=0 23 | RequireCourtyardDefinitions=0 24 | ProhibitOverlappingCourtyards=1 25 | MinTrackWidth=0.127 26 | MinViaDiameter=0.4572 27 | MinViaDrill=0.254 28 | MinMicroViaDiameter=0.2 29 | MinMicroViaDrill=0.09999999999999999 30 | MinHoleToHole=0.25 31 | TrackWidth1=0.15 32 | TrackWidth2=0.2 33 | TrackWidth3=0.342 34 | TrackWidth4=0.5 35 | TrackWidth5=0.7 36 | ViaDiameter1=0.7 37 | ViaDrill1=0.3 38 | ViaDiameter2=0.4572 39 | ViaDrill2=0.254 40 | ViaDiameter3=0.6 41 | ViaDrill3=0.3 42 | dPairWidth1=0.2 43 | dPairGap1=0.25 44 | dPairViaGap1=0.25 45 | SilkLineWidth=0.12 46 | SilkTextSizeV=1 47 | SilkTextSizeH=1 48 | SilkTextSizeThickness=0.15 49 | SilkTextItalic=0 50 | SilkTextUpright=1 51 | CopperLineWidth=0.2 52 | CopperTextSizeV=1.5 53 | CopperTextSizeH=1.5 54 | CopperTextThickness=0.3 55 | CopperTextItalic=0 56 | CopperTextUpright=1 57 | EdgeCutLineWidth=0.05 58 | CourtyardLineWidth=0.05 59 | OthersLineWidth=0.12 60 | OthersTextSizeV=1 61 | OthersTextSizeH=1 62 | OthersTextSizeThickness=0.15 63 | OthersTextItalic=0 64 | OthersTextUpright=1 65 | SolderMaskClearance=0 66 | SolderMaskMinWidth=0 67 | SolderPasteClearance=0 68 | SolderPasteRatio=-0 69 | [pcbnew/Layer.F.Cu] 70 | Name=F.Cu 71 | Type=0 72 | Enabled=1 73 | [pcbnew/Layer.In1.Cu] 74 | Name=In1.Cu 75 | Type=0 76 | Enabled=1 77 | [pcbnew/Layer.In2.Cu] 78 | Name=In2.Cu 79 | Type=0 80 | Enabled=1 81 | [pcbnew/Layer.In3.Cu] 82 | Name=In3.Cu 83 | Type=0 84 | Enabled=0 85 | [pcbnew/Layer.In4.Cu] 86 | Name=In4.Cu 87 | Type=0 88 | Enabled=0 89 | [pcbnew/Layer.In5.Cu] 90 | Name=In5.Cu 91 | Type=0 92 | Enabled=0 93 | [pcbnew/Layer.In6.Cu] 94 | Name=In6.Cu 95 | Type=0 96 | Enabled=0 97 | [pcbnew/Layer.In7.Cu] 98 | Name=In7.Cu 99 | Type=0 100 | Enabled=0 101 | [pcbnew/Layer.In8.Cu] 102 | Name=In8.Cu 103 | Type=0 104 | Enabled=0 105 | [pcbnew/Layer.In9.Cu] 106 | Name=In9.Cu 107 | Type=0 108 | Enabled=0 109 | [pcbnew/Layer.In10.Cu] 110 | Name=In10.Cu 111 | Type=0 112 | Enabled=0 113 | [pcbnew/Layer.In11.Cu] 114 | Name=In11.Cu 115 | Type=0 116 | Enabled=0 117 | [pcbnew/Layer.In12.Cu] 118 | Name=In12.Cu 119 | Type=0 120 | Enabled=0 121 | [pcbnew/Layer.In13.Cu] 122 | Name=In13.Cu 123 | Type=0 124 | Enabled=0 125 | [pcbnew/Layer.In14.Cu] 126 | Name=In14.Cu 127 | Type=0 128 | Enabled=0 129 | [pcbnew/Layer.In15.Cu] 130 | Name=In15.Cu 131 | Type=0 132 | Enabled=0 133 | [pcbnew/Layer.In16.Cu] 134 | Name=In16.Cu 135 | Type=0 136 | Enabled=0 137 | [pcbnew/Layer.In17.Cu] 138 | Name=In17.Cu 139 | Type=0 140 | Enabled=0 141 | [pcbnew/Layer.In18.Cu] 142 | Name=In18.Cu 143 | Type=0 144 | Enabled=0 145 | [pcbnew/Layer.In19.Cu] 146 | Name=In19.Cu 147 | Type=0 148 | Enabled=0 149 | [pcbnew/Layer.In20.Cu] 150 | Name=In20.Cu 151 | Type=0 152 | Enabled=0 153 | [pcbnew/Layer.In21.Cu] 154 | Name=In21.Cu 155 | Type=0 156 | Enabled=0 157 | [pcbnew/Layer.In22.Cu] 158 | Name=In22.Cu 159 | Type=0 160 | Enabled=0 161 | [pcbnew/Layer.In23.Cu] 162 | Name=In23.Cu 163 | Type=0 164 | Enabled=0 165 | [pcbnew/Layer.In24.Cu] 166 | Name=In24.Cu 167 | Type=0 168 | Enabled=0 169 | [pcbnew/Layer.In25.Cu] 170 | Name=In25.Cu 171 | Type=0 172 | Enabled=0 173 | [pcbnew/Layer.In26.Cu] 174 | Name=In26.Cu 175 | Type=0 176 | Enabled=0 177 | [pcbnew/Layer.In27.Cu] 178 | Name=In27.Cu 179 | Type=0 180 | Enabled=0 181 | [pcbnew/Layer.In28.Cu] 182 | Name=In28.Cu 183 | Type=0 184 | Enabled=0 185 | [pcbnew/Layer.In29.Cu] 186 | Name=In29.Cu 187 | Type=0 188 | Enabled=0 189 | [pcbnew/Layer.In30.Cu] 190 | Name=In30.Cu 191 | Type=0 192 | Enabled=0 193 | [pcbnew/Layer.B.Cu] 194 | Name=B.Cu 195 | Type=0 196 | Enabled=1 197 | [pcbnew/Layer.B.Adhes] 198 | Enabled=0 199 | [pcbnew/Layer.F.Adhes] 200 | Enabled=0 201 | [pcbnew/Layer.B.Paste] 202 | Enabled=1 203 | [pcbnew/Layer.F.Paste] 204 | Enabled=1 205 | [pcbnew/Layer.B.SilkS] 206 | Enabled=1 207 | [pcbnew/Layer.F.SilkS] 208 | Enabled=1 209 | [pcbnew/Layer.B.Mask] 210 | Enabled=1 211 | [pcbnew/Layer.F.Mask] 212 | Enabled=1 213 | [pcbnew/Layer.Dwgs.User] 214 | Enabled=0 215 | [pcbnew/Layer.Cmts.User] 216 | Enabled=0 217 | [pcbnew/Layer.Eco1.User] 218 | Enabled=1 219 | [pcbnew/Layer.Eco2.User] 220 | Enabled=0 221 | [pcbnew/Layer.Edge.Cuts] 222 | Enabled=1 223 | [pcbnew/Layer.Margin] 224 | Enabled=1 225 | [pcbnew/Layer.B.CrtYd] 226 | Enabled=1 227 | [pcbnew/Layer.F.CrtYd] 228 | Enabled=1 229 | [pcbnew/Layer.B.Fab] 230 | Enabled=0 231 | [pcbnew/Layer.F.Fab] 232 | Enabled=0 233 | [pcbnew/Layer.Rescue] 234 | Enabled=0 235 | [pcbnew/Netclasses] 236 | [pcbnew/Netclasses/Default] 237 | Name=Default 238 | Clearance=0.15 239 | TrackWidth=0.15 240 | ViaDiameter=0.7 241 | ViaDrill=0.3 242 | uViaDiameter=0.3 243 | uViaDrill=0.1 244 | dPairWidth=0.2 245 | dPairGap=0.25 246 | dPairViaGap=0.25 247 | -------------------------------------------------------------------------------- /Radar 2/Radar v2.pro: -------------------------------------------------------------------------------- 1 | update=2020 August 03, Monday 13:49:59 2 | last_client=kicad 3 | [general] 4 | version=1 5 | [schematic_editor] 6 | version=1 7 | PageLayoutDescrFile= 8 | PlotDirectoryName= 9 | SubpartIdSeparator=0 10 | SubpartFirstId=65 11 | NetFmtName=Pcbnew 12 | SpiceAjustPassiveValues=0 13 | LabSize=39 14 | ERC_TestSimilarLabels=1 15 | [pcbnew] 16 | version=1 17 | PageLayoutDescrFile= 18 | LastNetListRead=Radar v2.net 19 | CopperLayerCount=4 20 | BoardThickness=1.6 21 | AllowMicroVias=0 22 | AllowBlindVias=0 23 | RequireCourtyardDefinitions=0 24 | ProhibitOverlappingCourtyards=1 25 | MinTrackWidth=0.15 26 | MinViaDiameter=0.46 27 | MinViaDrill=0.254 28 | MinMicroViaDiameter=0.2 29 | MinMicroViaDrill=0.09999999999999999 30 | MinHoleToHole=0.25 31 | TrackWidth1=0.15 32 | TrackWidth2=0.2 33 | TrackWidth3=0.3 34 | TrackWidth4=0.33 35 | TrackWidth5=0.4 36 | TrackWidth6=0.5 37 | TrackWidth7=0.7 38 | TrackWidth8=1 39 | ViaDiameter1=0.46 40 | ViaDrill1=0.254 41 | ViaDiameter2=0.6 42 | ViaDrill2=0.3 43 | ViaDiameter3=0.8 44 | ViaDrill3=0.4 45 | dPairWidth1=0.2 46 | dPairGap1=0.25 47 | dPairViaGap1=0.25 48 | SilkLineWidth=0.12 49 | SilkTextSizeV=1 50 | SilkTextSizeH=1 51 | SilkTextSizeThickness=0.15 52 | SilkTextItalic=0 53 | SilkTextUpright=1 54 | CopperLineWidth=0.2 55 | CopperTextSizeV=1.5 56 | CopperTextSizeH=1.5 57 | CopperTextThickness=0.3 58 | CopperTextItalic=0 59 | CopperTextUpright=1 60 | EdgeCutLineWidth=0.05 61 | CourtyardLineWidth=0.05 62 | OthersLineWidth=0.12 63 | OthersTextSizeV=1 64 | OthersTextSizeH=1 65 | OthersTextSizeThickness=0.15 66 | OthersTextItalic=0 67 | OthersTextUpright=1 68 | SolderMaskClearance=0 69 | SolderMaskMinWidth=0 70 | SolderPasteClearance=0 71 | SolderPasteRatio=-0 72 | [pcbnew/Layer.F.Cu] 73 | Name=F.Cu 74 | Type=0 75 | Enabled=1 76 | [pcbnew/Layer.In1.Cu] 77 | Name=In1.Cu 78 | Type=0 79 | Enabled=1 80 | [pcbnew/Layer.In2.Cu] 81 | Name=In2.Cu 82 | Type=0 83 | Enabled=1 84 | [pcbnew/Layer.In3.Cu] 85 | Name=In3.Cu 86 | Type=0 87 | Enabled=0 88 | [pcbnew/Layer.In4.Cu] 89 | Name=In4.Cu 90 | Type=0 91 | Enabled=0 92 | [pcbnew/Layer.In5.Cu] 93 | Name=In5.Cu 94 | Type=0 95 | Enabled=0 96 | [pcbnew/Layer.In6.Cu] 97 | Name=In6.Cu 98 | Type=0 99 | Enabled=0 100 | [pcbnew/Layer.In7.Cu] 101 | Name=In7.Cu 102 | Type=0 103 | Enabled=0 104 | [pcbnew/Layer.In8.Cu] 105 | Name=In8.Cu 106 | Type=0 107 | Enabled=0 108 | [pcbnew/Layer.In9.Cu] 109 | Name=In9.Cu 110 | Type=0 111 | Enabled=0 112 | [pcbnew/Layer.In10.Cu] 113 | Name=In10.Cu 114 | Type=0 115 | Enabled=0 116 | [pcbnew/Layer.In11.Cu] 117 | Name=In11.Cu 118 | Type=0 119 | Enabled=0 120 | [pcbnew/Layer.In12.Cu] 121 | Name=In12.Cu 122 | Type=0 123 | Enabled=0 124 | [pcbnew/Layer.In13.Cu] 125 | Name=In13.Cu 126 | Type=0 127 | Enabled=0 128 | [pcbnew/Layer.In14.Cu] 129 | Name=In14.Cu 130 | Type=0 131 | Enabled=0 132 | [pcbnew/Layer.In15.Cu] 133 | Name=In15.Cu 134 | Type=0 135 | Enabled=0 136 | [pcbnew/Layer.In16.Cu] 137 | Name=In16.Cu 138 | Type=0 139 | Enabled=0 140 | [pcbnew/Layer.In17.Cu] 141 | Name=In17.Cu 142 | Type=0 143 | Enabled=0 144 | [pcbnew/Layer.In18.Cu] 145 | Name=In18.Cu 146 | Type=0 147 | Enabled=0 148 | [pcbnew/Layer.In19.Cu] 149 | Name=In19.Cu 150 | Type=0 151 | Enabled=0 152 | [pcbnew/Layer.In20.Cu] 153 | Name=In20.Cu 154 | Type=0 155 | Enabled=0 156 | [pcbnew/Layer.In21.Cu] 157 | Name=In21.Cu 158 | Type=0 159 | Enabled=0 160 | [pcbnew/Layer.In22.Cu] 161 | Name=In22.Cu 162 | Type=0 163 | Enabled=0 164 | [pcbnew/Layer.In23.Cu] 165 | Name=In23.Cu 166 | Type=0 167 | Enabled=0 168 | [pcbnew/Layer.In24.Cu] 169 | Name=In24.Cu 170 | Type=0 171 | Enabled=0 172 | [pcbnew/Layer.In25.Cu] 173 | Name=In25.Cu 174 | Type=0 175 | Enabled=0 176 | [pcbnew/Layer.In26.Cu] 177 | Name=In26.Cu 178 | Type=0 179 | Enabled=0 180 | [pcbnew/Layer.In27.Cu] 181 | Name=In27.Cu 182 | Type=0 183 | Enabled=0 184 | [pcbnew/Layer.In28.Cu] 185 | Name=In28.Cu 186 | Type=0 187 | Enabled=0 188 | [pcbnew/Layer.In29.Cu] 189 | Name=In29.Cu 190 | Type=0 191 | Enabled=0 192 | [pcbnew/Layer.In30.Cu] 193 | Name=In30.Cu 194 | Type=0 195 | Enabled=0 196 | [pcbnew/Layer.B.Cu] 197 | Name=B.Cu 198 | Type=0 199 | Enabled=1 200 | [pcbnew/Layer.B.Adhes] 201 | Enabled=0 202 | [pcbnew/Layer.F.Adhes] 203 | Enabled=0 204 | [pcbnew/Layer.B.Paste] 205 | Enabled=1 206 | [pcbnew/Layer.F.Paste] 207 | Enabled=1 208 | [pcbnew/Layer.B.SilkS] 209 | Enabled=1 210 | [pcbnew/Layer.F.SilkS] 211 | Enabled=1 212 | [pcbnew/Layer.B.Mask] 213 | Enabled=1 214 | [pcbnew/Layer.F.Mask] 215 | Enabled=1 216 | [pcbnew/Layer.Dwgs.User] 217 | Enabled=0 218 | [pcbnew/Layer.Cmts.User] 219 | Enabled=0 220 | [pcbnew/Layer.Eco1.User] 221 | Enabled=1 222 | [pcbnew/Layer.Eco2.User] 223 | Enabled=0 224 | [pcbnew/Layer.Edge.Cuts] 225 | Enabled=1 226 | [pcbnew/Layer.Margin] 227 | Enabled=1 228 | [pcbnew/Layer.B.CrtYd] 229 | Enabled=1 230 | [pcbnew/Layer.F.CrtYd] 231 | Enabled=1 232 | [pcbnew/Layer.B.Fab] 233 | Enabled=0 234 | [pcbnew/Layer.F.Fab] 235 | Enabled=0 236 | [pcbnew/Layer.Rescue] 237 | Enabled=0 238 | [pcbnew/Netclasses] 239 | [pcbnew/Netclasses/Default] 240 | Name=Default 241 | Clearance=0.15 242 | TrackWidth=0.15 243 | ViaDiameter=0.46 244 | ViaDrill=0.254 245 | uViaDiameter=0.3 246 | uViaDrill=0.1 247 | dPairWidth=0.2 248 | dPairGap=0.25 249 | dPairViaGap=0.25 250 | -------------------------------------------------------------------------------- /Radar MCU/Radar MCU.pro: -------------------------------------------------------------------------------- 1 | update=2019 December 19, Thursday 23:58:37 2 | last_client=kicad 3 | [general] 4 | version=1 5 | [schematic_editor] 6 | version=1 7 | PageLayoutDescrFile= 8 | PlotDirectoryName= 9 | SubpartIdSeparator=0 10 | SubpartFirstId=65 11 | NetFmtName=Pcbnew 12 | SpiceAjustPassiveValues=0 13 | LabSize=39 14 | ERC_TestSimilarLabels=1 15 | [pcbnew] 16 | version=1 17 | PageLayoutDescrFile= 18 | LastNetListRead=Radar MCU.net 19 | CopperLayerCount=4 20 | BoardThickness=1.6 21 | AllowMicroVias=0 22 | AllowBlindVias=0 23 | RequireCourtyardDefinitions=0 24 | ProhibitOverlappingCourtyards=1 25 | MinTrackWidth=0.127 26 | MinViaDiameter=0.4572 27 | MinViaDrill=0.254 28 | MinMicroViaDiameter=0.2 29 | MinMicroViaDrill=0.09999999999999999 30 | MinHoleToHole=0.25 31 | TrackWidth1=0.15 32 | TrackWidth2=0.2 33 | TrackWidth3=0.3 34 | TrackWidth4=0.5 35 | TrackWidth5=0.7 36 | TrackWidth6=1 37 | ViaDiameter1=0.46 38 | ViaDrill1=0.254 39 | ViaDiameter2=0.6 40 | ViaDrill2=0.3 41 | ViaDiameter3=0.7 42 | ViaDrill3=0.4 43 | ViaDiameter4=1 44 | ViaDrill4=0.5 45 | dPairWidth1=0.2 46 | dPairGap1=0.25 47 | dPairViaGap1=0.25 48 | SilkLineWidth=0.12 49 | SilkTextSizeV=1 50 | SilkTextSizeH=1 51 | SilkTextSizeThickness=0.15 52 | SilkTextItalic=0 53 | SilkTextUpright=1 54 | CopperLineWidth=0.2 55 | CopperTextSizeV=1.5 56 | CopperTextSizeH=1.5 57 | CopperTextThickness=0.3 58 | CopperTextItalic=0 59 | CopperTextUpright=1 60 | EdgeCutLineWidth=0.05 61 | CourtyardLineWidth=0.05 62 | OthersLineWidth=0.12 63 | OthersTextSizeV=1 64 | OthersTextSizeH=1 65 | OthersTextSizeThickness=0.15 66 | OthersTextItalic=0 67 | OthersTextUpright=1 68 | SolderMaskClearance=0 69 | SolderMaskMinWidth=0 70 | SolderPasteClearance=0 71 | SolderPasteRatio=-0 72 | [pcbnew/Layer.F.Cu] 73 | Name=F.Cu 74 | Type=0 75 | Enabled=1 76 | [pcbnew/Layer.In1.Cu] 77 | Name=In1.Cu 78 | Type=0 79 | Enabled=1 80 | [pcbnew/Layer.In2.Cu] 81 | Name=In2.Cu 82 | Type=0 83 | Enabled=1 84 | [pcbnew/Layer.In3.Cu] 85 | Name=In3.Cu 86 | Type=0 87 | Enabled=0 88 | [pcbnew/Layer.In4.Cu] 89 | Name=In4.Cu 90 | Type=0 91 | Enabled=0 92 | [pcbnew/Layer.In5.Cu] 93 | Name=In5.Cu 94 | Type=0 95 | Enabled=0 96 | [pcbnew/Layer.In6.Cu] 97 | Name=In6.Cu 98 | Type=0 99 | Enabled=0 100 | [pcbnew/Layer.In7.Cu] 101 | Name=In7.Cu 102 | Type=0 103 | Enabled=0 104 | [pcbnew/Layer.In8.Cu] 105 | Name=In8.Cu 106 | Type=0 107 | Enabled=0 108 | [pcbnew/Layer.In9.Cu] 109 | Name=In9.Cu 110 | Type=0 111 | Enabled=0 112 | [pcbnew/Layer.In10.Cu] 113 | Name=In10.Cu 114 | Type=0 115 | Enabled=0 116 | [pcbnew/Layer.In11.Cu] 117 | Name=In11.Cu 118 | Type=0 119 | Enabled=0 120 | [pcbnew/Layer.In12.Cu] 121 | Name=In12.Cu 122 | Type=0 123 | Enabled=0 124 | [pcbnew/Layer.In13.Cu] 125 | Name=In13.Cu 126 | Type=0 127 | Enabled=0 128 | [pcbnew/Layer.In14.Cu] 129 | Name=In14.Cu 130 | Type=0 131 | Enabled=0 132 | [pcbnew/Layer.In15.Cu] 133 | Name=In15.Cu 134 | Type=0 135 | Enabled=0 136 | [pcbnew/Layer.In16.Cu] 137 | Name=In16.Cu 138 | Type=0 139 | Enabled=0 140 | [pcbnew/Layer.In17.Cu] 141 | Name=In17.Cu 142 | Type=0 143 | Enabled=0 144 | [pcbnew/Layer.In18.Cu] 145 | Name=In18.Cu 146 | Type=0 147 | Enabled=0 148 | [pcbnew/Layer.In19.Cu] 149 | Name=In19.Cu 150 | Type=0 151 | Enabled=0 152 | [pcbnew/Layer.In20.Cu] 153 | Name=In20.Cu 154 | Type=0 155 | Enabled=0 156 | [pcbnew/Layer.In21.Cu] 157 | Name=In21.Cu 158 | Type=0 159 | Enabled=0 160 | [pcbnew/Layer.In22.Cu] 161 | Name=In22.Cu 162 | Type=0 163 | Enabled=0 164 | [pcbnew/Layer.In23.Cu] 165 | Name=In23.Cu 166 | Type=0 167 | Enabled=0 168 | [pcbnew/Layer.In24.Cu] 169 | Name=In24.Cu 170 | Type=0 171 | Enabled=0 172 | [pcbnew/Layer.In25.Cu] 173 | Name=In25.Cu 174 | Type=0 175 | Enabled=0 176 | [pcbnew/Layer.In26.Cu] 177 | Name=In26.Cu 178 | Type=0 179 | Enabled=0 180 | [pcbnew/Layer.In27.Cu] 181 | Name=In27.Cu 182 | Type=0 183 | Enabled=0 184 | [pcbnew/Layer.In28.Cu] 185 | Name=In28.Cu 186 | Type=0 187 | Enabled=0 188 | [pcbnew/Layer.In29.Cu] 189 | Name=In29.Cu 190 | Type=0 191 | Enabled=0 192 | [pcbnew/Layer.In30.Cu] 193 | Name=In30.Cu 194 | Type=0 195 | Enabled=0 196 | [pcbnew/Layer.B.Cu] 197 | Name=B.Cu 198 | Type=0 199 | Enabled=1 200 | [pcbnew/Layer.B.Adhes] 201 | Enabled=0 202 | [pcbnew/Layer.F.Adhes] 203 | Enabled=0 204 | [pcbnew/Layer.B.Paste] 205 | Enabled=1 206 | [pcbnew/Layer.F.Paste] 207 | Enabled=1 208 | [pcbnew/Layer.B.SilkS] 209 | Enabled=1 210 | [pcbnew/Layer.F.SilkS] 211 | Enabled=1 212 | [pcbnew/Layer.B.Mask] 213 | Enabled=1 214 | [pcbnew/Layer.F.Mask] 215 | Enabled=1 216 | [pcbnew/Layer.Dwgs.User] 217 | Enabled=0 218 | [pcbnew/Layer.Cmts.User] 219 | Enabled=0 220 | [pcbnew/Layer.Eco1.User] 221 | Enabled=1 222 | [pcbnew/Layer.Eco2.User] 223 | Enabled=0 224 | [pcbnew/Layer.Edge.Cuts] 225 | Enabled=1 226 | [pcbnew/Layer.Margin] 227 | Enabled=1 228 | [pcbnew/Layer.B.CrtYd] 229 | Enabled=1 230 | [pcbnew/Layer.F.CrtYd] 231 | Enabled=1 232 | [pcbnew/Layer.B.Fab] 233 | Enabled=0 234 | [pcbnew/Layer.F.Fab] 235 | Enabled=0 236 | [pcbnew/Layer.Rescue] 237 | Enabled=0 238 | [pcbnew/Netclasses] 239 | [pcbnew/Netclasses/Default] 240 | Name=Default 241 | Clearance=0.15 242 | TrackWidth=0.15 243 | ViaDiameter=0.46 244 | ViaDrill=0.254 245 | uViaDiameter=0.3 246 | uViaDrill=0.1 247 | dPairWidth=0.2 248 | dPairGap=0.25 249 | dPairViaGap=0.25 250 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_TQP5523.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_TQP5523.h" 3 | #include "CK_GPIO.h" 4 | #include "CK_TIME_HAL.h" 5 | #include "USBD_CDC/CK_USBD_INTERFACE.h" 6 | 7 | /* 8 | * PB0 -> DET_OUT (ADC12_IN8), 0.3 to 1V output voltage to indicate output dBm of PA 9 | * PB1 -> PA_EN Active High. Pulled Down by default. (When radar is functioning activate it.) 10 | * 11 | */ 12 | 13 | #define DET_OUT_GPIO GPIOB 14 | #define DET_OUT_PIN 0 15 | 16 | #define PA_EN_GPIO GPIOB 17 | #define PA_EN_PIN 1 18 | 19 | uint32_t adc_data = 0; 20 | float detector_output_voltage = 0.0f; 21 | int detector_output_dBm = 0; 22 | 23 | uint32_t previousTime = 0; 24 | uint32_t currentTime = 0; 25 | 26 | int state = 0; 27 | int isMeasured = 0; 28 | 29 | // TQP5523 Datasheet Page 6 30 | uint8_t TQP5523_DBM_PROFILE[6] = {8, 16, 20, 22, 24, 26}; 31 | float TQP5523_VOLTAGE_PROFILE[6] = {0.4, 0.5, 0.6, 0.7, 0.8, 0.9}; 32 | 33 | void CK_TQP5523_Init(void){ 34 | 35 | // PA_EN Pin 36 | CK_GPIO_Init(PA_EN_GPIO, PA_EN_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_MEDIUM, CK_GPIO_NOPUPD); 37 | 38 | CK_TQP5523_Disable(); 39 | 40 | // PB0 ADC12_IN8 (Channel 8 at either ADC1 or 2) 41 | 42 | // Default sampling time is 3 cycle set in ADC_SMPRx register 43 | // so one conversion takes 12(bitresolution)+3 cycles = 15 cycles 44 | // For 42MHz ADCCLK it makes 2.8Msps 45 | // Default bit resolution is 12bit at ADC_CR1 register. 46 | 47 | // Channel selection 48 | // ADCx_SQR1 L[3:0] bits default 0 which is only 1 channel conversion 49 | 50 | RCC->APB2ENR |= (1u << 9); // 8 is ADC1, 9 ADC2 and 10 ADC3 51 | GPIOB->MODER |= (3u << 0); // pin 0 analog mode. 52 | 53 | // APB2 clock is 82MHz, ADCCLK = APB2 / prescalar 54 | // 0->2, 1->4, 2->6, 3->8 (Default is 2, 0u << 16) 55 | // Main ADC Clock for all ADC and fix. 56 | // ADCCLK = 82/6 = 14 MHz sampling is configured according to CK_ADC_DMA 57 | ADC->CCR |= (2u << 16); 58 | 59 | //0->3cycle, 1->15, 2->28, 3->56, 4->84, 5->112, 6->144, 7->480 60 | // ADC2 Channel 8 Sampling time = 12 + 480 = 492 61 | // Tsampling = 492 * (1/14MHz) = 35 microsecond for channel 8 62 | ADC2->SMPR2 |= (7u << 24); // sampling time cycle selection for channel 8 63 | 64 | // I assing the channel 8 to the first conversion of ADC1 65 | ADC2->SQR3 |= (8u << 0); 66 | 67 | ADC2->CR1 |= (1u << 5); // End of conversion interrupt enable. 68 | 69 | // Call start conversion whenever want to read adc. 70 | // It will go to interrupt once it is finished. 71 | // Or, continuous conversion goes to interrupt every 50microsec. 72 | //ADC2->CR2 |= (1u << 1); // continuous conversion, 73 | 74 | ADC2->CR2 |= (1u << 0); // Enable ADC 75 | 76 | HAL_NVIC_EnableIRQ(ADC_IRQn); 77 | 78 | } 79 | 80 | void CK_TQP5523_Update(void){ 81 | 82 | currentTime = CK_TIME_GetMicroSec(); 83 | float dTime = currentTime - previousTime; 84 | 85 | // 50Hz 86 | if(dTime > 50000){ 87 | 88 | previousTime = currentTime; 89 | 90 | if(state == 0){ 91 | 92 | state = 1; 93 | CK_TQP5523_StartConversion(); 94 | 95 | } 96 | else{ 97 | 98 | state = 0; 99 | CK_USBD_StringPrint("TQP55 Detector Output Voltage: "); 100 | CK_USBD_FloatPrintln(detector_output_voltage); 101 | 102 | CK_USBD_Transmit(); 103 | 104 | } 105 | 106 | } 107 | } 108 | 109 | void CK_TQP5523_CheckOutputPower(void){ 110 | 111 | isMeasured = 0; 112 | 113 | CK_TQP5523_StartConversion(); 114 | 115 | while(!isMeasured); 116 | 117 | for(int i = 0; i < 5; i++){ 118 | 119 | float volt1 = TQP5523_VOLTAGE_PROFILE[i]; 120 | float volt2 = TQP5523_VOLTAGE_PROFILE[i+1]; 121 | 122 | if(detector_output_voltage >= volt1 && detector_output_voltage <= volt2){ 123 | 124 | if((detector_output_voltage - volt1) < (detector_output_voltage - volt2)){ 125 | detector_output_dBm = TQP5523_DBM_PROFILE[i]; 126 | } 127 | else{ 128 | detector_output_dBm = TQP5523_DBM_PROFILE[i+1]; 129 | } 130 | 131 | } 132 | else if(detector_output_voltage < volt1){ 133 | //detector_output_dBm = 0; 134 | } 135 | else if(detector_output_voltage > volt2){ 136 | //detector_output_dBm = 27; 137 | } 138 | 139 | } 140 | 141 | } 142 | 143 | void CK_TQP5523_StartConversion(void){ 144 | 145 | // Conversion start, can be set only when adc is enabled 146 | ADC2->CR2 |= (1u << 30); 147 | } 148 | 149 | void CK_TQP5523_Disable(void){ 150 | 151 | CK_GPIO_ClearPin(PA_EN_GPIO, PA_EN_PIN); 152 | } 153 | 154 | void CK_TQP5523_Enable(void){ 155 | 156 | CK_GPIO_SetPin(PA_EN_GPIO, PA_EN_PIN); 157 | } 158 | 159 | float CK_TQP5523_ReadDetectorOutputVoltage(void){ 160 | 161 | return detector_output_voltage; 162 | } 163 | 164 | int CK_TQP5523_ReadDetectorOutputDBM(void){ 165 | 166 | return detector_output_dBm; 167 | } 168 | 169 | void ADC_IRQHandler(void){ 170 | 171 | /* 172 | static uint32_t t1 = 0; 173 | static int temp = 0; 174 | if(temp==0){ 175 | temp=1; 176 | t1 = CK_TIME_GetMicroSec(); 177 | } 178 | else{ 179 | uint32_t t2 = CK_TIME_GetMicroSec() - t1; 180 | uint32_t t3 = t2; 181 | temp=0; 182 | } 183 | */ 184 | 185 | uint32_t stat1 = ADC2->SR; 186 | 187 | if((stat1 & (1u << 1)) == 2){ 188 | 189 | adc_data = ADC2->DR & 0xFFFF; 190 | detector_output_voltage = (float)adc_data / 4096.0; 191 | detector_output_voltage *= 3.0; 192 | 193 | isMeasured = 1; 194 | 195 | ADC2->SR = 0; // Clear status register. 196 | 197 | } 198 | } 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_SYSTEM.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_SYSTEM.h" 3 | 4 | #define CK_PWR_CR_VOS_SCLAE1 3u << 14 // SCALE1 SELECTED (FOR 180 MHz ) 5 | #define CK_PWR_CR_ODEN 1u << 16 // Overdrive for 180MHz necessary 6 | #define CK_PWR_CR_ODSWEN 1u << 17 // Overdrive switching enable 7 | 8 | #define CK_RCC_APB1ENR_PWREN 1u << 28 // PWREN BIT 9 | #define CK_RCC_CR_HSEON 1u << 16 // External Osc On 10 | #define CK_RCC_CR_HSERDY 1u << 17 // HSE Ready Bit 11 | #define CK_RCC_CR_HSEBYP 1u << 18 // Bypass Mode for disabling PLL 12 | #define CK_RCC_CR_PLLONOFF 1u << 24 // PLL ON OFF Bit 13 | #define CK_RCC_CR_PLLRDY 1u << 25 // PLL ON OFF Bit 14 | 15 | #define CK_RCC_PLLCFGR_PLLSource_HSE 1u << 22 // HSE Selected as PLL Source 16 | #define CK_RCC_PLLCFGR_PLLM_8 8u << 0 // PPLM is at default 16 we write 8 instead 17 | #define CK_RCC_PLLCFGR_PLLM_4 4u << 0 // PPLM is at default 16 we write 8 instead 18 | #define CK_RCC_PLLCFGR_PLLN_168 168u << 6 // PPLN is not zero at default we clear first 19 | #define CK_RCC_PLLCFGR_PLLN_180 180u << 6 // PPLN is not zero at default we clear first 20 | #define CK_RCC_PLLCFGR_PLLN_360 360u << 6 // PPLN is not zero at default we clear first 21 | #define CK_RCC_PLLCFGR_PLLN_336 336u << 6 // PPLN is not zero at default we clear first 22 | #define CK_RCC_PLLCFGR_PLLQ_7 7u << 24 // Defines USB Clock 360/7 = 48MHz 23 | 24 | #define CK_FLASH_ACR_LATENCY_5 5u << 0 // Latency is 5 25 | #define CK_RCC_CFGR_SYSCLKSOURCE_PLLCLK 2u << 0 // PLL Selected as System Clock 26 | #define CK_RCC_CFGR_PRE1_DIV4 5u << 10 // PRE1 DIV4 PLLN/4 => 180/4 = 45MHz OR 168/4 = 42 27 | #define CK_RCC_CFGR_PRE2_DIV2 4u << 13 // PRE2 DIV2 PLLN/2 => 180/2 = 90MHz OR 168/4 = 84 28 | 29 | void CK_SYSTEM_SetSystemClock(systemClock_e clk){ 30 | 31 | if(clk == SYSTEM_CLK_180MHz){ 32 | 33 | F_CPU = 180000000L; 34 | 35 | RCC->APB1ENR |= CK_RCC_APB1ENR_PWREN; 36 | 37 | RCC->CR |= CK_RCC_CR_HSEON; 38 | while((RCC->CR & CK_RCC_CR_HSERDY) == 0);//Wait Until HSE Ready 39 | 40 | RCC->CR |= CK_RCC_CR_HSEBYP;//First Disable PLL by going Bypass Mode to set parameters 41 | while((RCC->CR & CK_RCC_CR_PLLRDY) != 0);/* Wait till PLL is ready */ 42 | 43 | RCC->PLLCFGR = 0; 44 | /*PLLP->DIV2 is selected (00) when we erase register*/ 45 | RCC->PLLCFGR |= CK_RCC_PLLCFGR_PLLM_4 | CK_RCC_PLLCFGR_PLLN_180 | CK_RCC_PLLCFGR_PLLSource_HSE | CK_RCC_PLLCFGR_PLLQ_7; 46 | 47 | RCC->CR |= CK_RCC_CR_PLLONOFF;//Enable PLL 48 | while((RCC->CR & CK_RCC_CR_PLLRDY) == 0);/* Wait till PLL is ready */ 49 | 50 | PWR->CR |= CK_PWR_CR_ODEN | CK_PWR_CR_ODSWEN; 51 | 52 | FLASH->ACR |= CK_FLASH_ACR_LATENCY_5; 53 | 54 | RCC->CFGR |= CK_RCC_CFGR_SYSCLKSOURCE_PLLCLK | CK_RCC_CFGR_PRE1_DIV4 | CK_RCC_CFGR_PRE2_DIV2; 55 | while(((RCC->CFGR>>2) & 2u) != 2);//Wait SWS Status to show PLL enabled 56 | 57 | // Calculate system clock frequency and update HAL variable 58 | // Peripherals might use this variable in their configuration. 59 | SystemCoreClock = CK_SYSTEM_GetSystemClock(); 60 | 61 | } 62 | else if(clk == SYSTEM_CLK_168MHz){ 63 | 64 | F_CPU = 168000000L; 65 | 66 | RCC->APB1ENR |= CK_RCC_APB1ENR_PWREN; 67 | 68 | RCC->CR |= CK_RCC_CR_HSEON; 69 | while((RCC->CR & CK_RCC_CR_HSERDY) == 0);//Wait Until HSE Ready 70 | 71 | RCC->CR |= CK_RCC_CR_HSEBYP;//First Disable PLL by going Bypass Mode to set parameters 72 | while((RCC->CR & CK_RCC_CR_PLLRDY) != 0);/* Wait till PLL is ready */ 73 | 74 | RCC->PLLCFGR = 0; 75 | /*PLLP->DIV2 is selected (00) when we erase register*/ 76 | RCC->PLLCFGR |= CK_RCC_PLLCFGR_PLLM_4 | CK_RCC_PLLCFGR_PLLN_168 | CK_RCC_PLLCFGR_PLLSource_HSE | CK_RCC_PLLCFGR_PLLQ_7; 77 | 78 | RCC->CR |= CK_RCC_CR_PLLONOFF;//Enable PLL 79 | while((RCC->CR & CK_RCC_CR_PLLRDY) == 0);/* Wait till PLL is ready */ 80 | 81 | PWR->CR |= CK_PWR_CR_ODEN | CK_PWR_CR_ODSWEN; 82 | 83 | FLASH->ACR |= CK_FLASH_ACR_LATENCY_5; 84 | 85 | RCC->CFGR |= CK_RCC_CFGR_SYSCLKSOURCE_PLLCLK | CK_RCC_CFGR_PRE1_DIV4 | CK_RCC_CFGR_PRE2_DIV2; 86 | while(((RCC->CFGR>>2) & 2u) != 2);//Wait SWS Status to show PLL enabled 87 | 88 | // Calculate system clock frequency and update HAL variable 89 | // Peripherals might use this variable in their configuration. 90 | SystemCoreClock = CK_SYSTEM_GetSystemClock(); 91 | 92 | } 93 | 94 | // To test system clocks 180 180 45 90 Mhz should be seen for STM32F429 95 | // To test system clocks 168 168 42 84 Mhz should be seen for STM32F405 96 | uint32_t frequencies = HAL_RCC_GetHCLKFreq(); 97 | frequencies = HAL_RCC_GetHCLKFreq(); 98 | frequencies = (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1)>> RCC_CFGR_PPRE1_Pos]); 99 | frequencies = HAL_RCC_GetPCLK2Freq(); 100 | UNUSED(frequencies); 101 | 102 | } 103 | 104 | uint32_t CK_SYSTEM_GetSystemClock(void){ 105 | 106 | // External cyrstal connected to MCU 107 | uint64_t EXTERNAL_CRSYTAL = 8000000UL; 108 | 109 | uint32_t pllm = 0U, pllvco = 0U, pllp = 0U; 110 | 111 | uint32_t sysclockfreq = 0U; 112 | 113 | pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; 114 | pllvco = (uint32_t) ((((uint64_t) EXTERNAL_CRSYTAL * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm); 115 | pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U) *2U); 116 | 117 | sysclockfreq = pllvco/pllp; 118 | 119 | return sysclockfreq; 120 | 121 | } 122 | 123 | -------------------------------------------------------------------------------- /Radar_Python/Radar_Plot.py: -------------------------------------------------------------------------------- 1 | # pip3 install pyserial 2 | 3 | import serial.tools.list_ports 4 | import numpy as np 5 | import matplotlib.pyplot as mp 6 | import peakutils 7 | import time 8 | 9 | ''' 10 | READ HERE: 11 | If i sample 10k in one second then i can plot one fft upto 5KHz once in a second. 12 | But i need higher update rate for good plot so i can sample 10K in 0.1 sec for example and plot fft upto 5k every 0.1sec 13 | To achieve that my system should be able to sample 10K * 10 = 100K samples in one second. 14 | 44100 samples can give fft of 20k bandwidth for one sec or 15 | 512*20 samples can give fft of 10K bandwitdh and since Fs = 200K 16 | i can take 512*20 samples of fft every 512*20 / Fs seconds. 17 | 18 | ''' 19 | 20 | record_file = open("data_record.txt", "r") 21 | 22 | data = str(record_file.readline()) 23 | RECORD_COUNTER = int(data[0:len(data)-1]) 24 | print("Record Counter: ", str(RECORD_COUNTER)) 25 | 26 | data = str(record_file.readline()) 27 | RECORD_TIME = int(data[0:len(data)-1]) 28 | print("Record Time: ", str(RECORD_TIME), " sec.") 29 | 30 | data = str(record_file.readline()) 31 | SWEEP_TIME = int(data[0:len(data)-1]) / 1000000 32 | print("Sweep Time : ", str(SWEEP_TIME), " microsec.") 33 | 34 | data = str(record_file.readline()) 35 | SWEEP_GAP = int(data[0:len(data)-1]) / 1000000 36 | print("Sweep Gap : ", str(SWEEP_GAP), " microsec.") 37 | 38 | data = str(record_file.readline()) 39 | SAMPLING_FREQUENCY = int(data[0:len(data)-1]) 40 | print("Sampling Freqeuncy : ", str(SAMPLING_FREQUENCY), " Hz.") 41 | 42 | data = str(record_file.readline()) 43 | NUMBER_OF_SAMPLES = int(data[0:len(data)-1]) 44 | print("Samples per sweep : ", str(NUMBER_OF_SAMPLES)) 45 | 46 | data = str(record_file.readline()) 47 | TX_MODE = int(data[0:len(data)-1]) 48 | print("Tx Mode : ", str(TX_MODE)) 49 | 50 | data = str(record_file.readline()) 51 | TX_POWER_DBM = int(data[0:len(data)-1]) 52 | print("Tx Power : ", str(TX_POWER_DBM), " dBm.") 53 | 54 | data = str(record_file.readline()) 55 | hz_per_m = int(data[0:len(data)-1]) 56 | print("Hz per m : ", str(hz_per_m)) 57 | 58 | FREQ_RANGE = 10000 59 | 60 | def Moving_Average_Filter(a, n = 10): 61 | 62 | ret = np.cumsum(a, dtype=float) 63 | ret[n:] = ret[n:] - ret[:-n] 64 | return ret[n - 1:] / n 65 | 66 | 67 | def FFT_Calculate(sample_data, sample_period, window = None, average = 1): 68 | 69 | if window: 70 | w = window(len(sample_data)) 71 | sample_data = [sample_data[i] * w[i] for i in range(len(w))] 72 | 73 | fs = 0.5/float(sample_period) 74 | fft_ = np.fft.rfft(sample_data) 75 | 76 | averages = average 77 | fft_ = Moving_Average_Filter(np.abs(fft_), averages) 78 | bins = len(fft_) 79 | f_step = fs/bins 80 | fx = [f_step*i for i in range(0, bins)] 81 | 82 | #peakIndexes = peakutils.indexes(finalFFT, 0.025, min_dist=50, thres_abs=True) 83 | 84 | return fx, fft_ 85 | 86 | def Time_Plot(samples): 87 | 88 | time_range = 0.1 # sec 89 | time_step = np.linspace(0.0, time_range, len(samples)) 90 | 91 | ax1.clear() 92 | 93 | # mp.ylim(2, 3) # limit y axis between var1 and var2 94 | # mp.xlim(0, len(time_step)) # limit y axis between var1 and var2 95 | 96 | mp.xlabel('Time') 97 | mp.ylabel('Value') 98 | 99 | mp.grid() 100 | 101 | ax1.plot(time_step, samples, 'c') 102 | 103 | # Calculate 104 | mp.pause(0.01) 105 | 106 | def Freq_Plot(samples, freq_bin, sampling_freq, freq_range, ylim, average): 107 | 108 | if freq_range >= freq_bin: 109 | freq_range = freq_bin 110 | 111 | fx, fy = FFT_Calculate(samples, 1 / sampling_freq, np.hamming, average) 112 | 113 | ax1.clear() 114 | 115 | mp.ylim(0, ylim) # limit y axis between var1 and var2 116 | mp.xlim(0, len(fx)/(freq_bin / (freq_range * 2))) # limit x axis between var1 and var2 117 | #mp.xlim(0, len(fx)) # limit x axis between var1 and var2 118 | 119 | mp.xlabel('Freq') 120 | mp.ylabel('Amplitude') 121 | 122 | mp.grid() 123 | 124 | ax1.plot(fx, fy, 'c') 125 | 126 | mp.pause(freq_bin/sampling_freq) 127 | #time.sleep(freq_bin/sampling_freq) 128 | 129 | def Freq_Plot2(samples, sampling_freq, ylim, average): 130 | 131 | fx, fy = FFT_Calculate(samples, 1 / sampling_freq, np.hamming, average) 132 | 133 | ax1.clear() 134 | 135 | mp.ylim(0, ylim) # limit y axis between var1 and var2 136 | mp.xlim(0, len(fx)) # limit x axis between var1 and var2 137 | 138 | mp.xlabel('Freq') 139 | mp.ylabel('Amplitude') 140 | 141 | mp.grid() 142 | 143 | ax1.plot(fx, fy, 'c') 144 | 145 | mp.pause(0.01) 146 | 147 | 148 | fig = mp.figure(figsize=(12, 6)) 149 | ax1 = fig.add_subplot(1, 1, 1) 150 | 151 | # Decode data_record 152 | sample_array = [] 153 | 154 | # Number of lines in the recorded text file. I set it to a large number for now. 155 | line_number_textFile = 0 156 | 157 | while line_number_textFile < RECORD_COUNTER: 158 | 159 | sample_line = record_file.readline() 160 | samples_hex = bytes.fromhex(sample_line) # get hex data from string 161 | length_line = len(samples_hex) 162 | 163 | if length_line > 0: 164 | 165 | index = 0 166 | while index < length_line: 167 | 168 | current_sample_16bit = (samples_hex[index] << 8) | (samples_hex[index+1]) 169 | 170 | current_sample_float = (current_sample_16bit / 2**10) * 5.0 171 | 172 | index += 2 173 | sample_array.append(round(current_sample_float, 3)) 174 | 175 | if len(sample_array) == FREQ_RANGE: 176 | 177 | #Time_Plot(sample_array) 178 | #Freq_Plot(sample_array, FREQ_RANGE, SAMPLING_FREQUENCY, freq_range=250000, ylim=10000, average=10) 179 | Freq_Plot2(sample_array, SAMPLING_FREQUENCY, ylim=1000, average=1) 180 | 181 | sample_array.clear() 182 | 183 | # move to the next line 184 | line_number_textFile += 1 185 | 186 | else: 187 | # all done exit loop 188 | line_number_textFile += 1 189 | 190 | exit(1) 191 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_ADC_DMA.c: -------------------------------------------------------------------------------- 1 | 2 | #include "stm32f4xx.h" 3 | 4 | #include "USBD_CDC/CK_USBD_INTERFACE.h" 5 | #include "CK_TIME_HAL.h" 6 | #include "CK_GPIO.h" 7 | #include "CK_ADC_DMA.h" 8 | 9 | // Debug timing has CK_ADC_DMA_Start(), use it without main loop. 10 | #define DEBUG_TIMING 0 11 | 12 | #define TEST_MODE 0 13 | 14 | #define ADC_BUFFER_SIZE 512 15 | 16 | uint16_t adc_dma_buffer1[ADC_BUFFER_SIZE]; 17 | 18 | uint32_t adc_t1 = 0, adc_t2 = 0, adc_t3 = 0; 19 | 20 | int samplingIsCompleted = 0; 21 | 22 | void CK_ADC_DMA_Init(void){ 23 | 24 | RCC->AHB1ENR |= (1u << 22); // DMA2 clock enable 25 | RCC->APB2ENR |= (1u << 8); // 8 is ADC1, 9 ADC2 and 10 ADC3 26 | 27 | // PC0 ADC123_IN10 (Channel 10 at either ADC1,2 or 3) 28 | GPIOC->MODER |= (3u << 0); // pin 0 is in analog mode. 29 | 30 | // DMA2 Stream 0, Channel 0 is ADC1 31 | // Clear flags before enabling DMA 32 | DMA2->LIFCR = 0x3D << 0; 33 | 34 | // Set peripheral data register address 35 | DMA2_Stream0->PAR = (uint32_t)(&ADC1->DR); 36 | 37 | DMA2_Stream0->M0AR = (uint32_t)(&adc_dma_buffer1); 38 | 39 | // Every ADC_BUFFER_SIZE transfer will create interrupt i suppose. 40 | // Enabling DMA again will load the same value 41 | DMA2_Stream0->NDTR = ADC_BUFFER_SIZE; 42 | 43 | // Half and Full Transfer Complete 44 | DMA2_Stream0->CR |= (1u << 3) | (1u << 4); 45 | 46 | // DMA is flow controller 47 | DMA2_Stream0->CR |= (0u << 5); 48 | 49 | // Data transfer direction is Peripheral to Memory, Memory address increment after each data tx 50 | DMA2_Stream0->CR |= (0u << 6) | (1 << 10); 51 | 52 | // Circular Mode, Double Buffer Mode 53 | // DMA2_Stream0->CR |= (1u << 8) | (1u << 18); 54 | 55 | // In normal mode NDTR = 0 when Full TX is done. 56 | // Use CK_ADC_DMA_Start() for starting conversion and dma transfer again after Full TX. 57 | DMA2_Stream0->CR |= (0u << 8) | (0u << 18); 58 | 59 | // Peripheral size 16 bit, Memory size 16 bit, Priority very high, channel 0 is selected 60 | DMA2_Stream0->CR |= (1u << 11) | (1u << 13) | (3u << 16) | (0u << 25); 61 | 62 | // Enable interrupt 63 | NVIC_EnableIRQ(DMA2_Stream0_IRQn); 64 | 65 | // APB2 clock is 84MHz, ADCCLK = APB2 / prescalar 66 | // 0->2, 1->4, 2->6, 3->8 67 | // ADCCLK = 82/6 = 14 MHz. 68 | ADC->CCR |= (2u << 16); 69 | 70 | // 0->3cycle, 1->15, 2->28, 3->56, 4->84, 5->112, 6->144, 7->480 71 | // Tsampling = (12 (fix adc 12 bit) + 15 cycle) * (1/14MHz) = 1.92 microsecond 72 | // Fsampling = 520KSample / sec for channel 10 73 | ADC1->SMPR1 |= (1u << 0); 74 | 75 | // I assing the channel 10 to the first conversion 76 | ADC1->SQR3 |= (10u << 0); 77 | 78 | //ADC1->CR1 |= (1u << 5); // End of conversion interrupt enable. 79 | 80 | ADC1->CR2 |= (1u << 1); // continuous conversion, 81 | 82 | ADC1->CR2 |= (1u << 0) | (1u << 8) | (1u << 9); // Enable ADC, DMA, DDS 83 | 84 | #if DEBUG_TIMING 85 | 86 | CK_ADC_DMA_Start(); 87 | 88 | adc_t1 = CK_TIME_GetMicroSec(); 89 | 90 | #endif 91 | } 92 | 93 | void CK_ADC_DMA_Start(void){ 94 | 95 | samplingIsCompleted = 0; 96 | 97 | CK_ADC_DMA_DMAStop(); 98 | CK_ADC_DMA_ADCStop(); 99 | 100 | // DMA2 Stream0 Clear Interrupts 101 | DMA2->LIFCR = 0x3D << 0; 102 | 103 | // ADC1 Clear Interrupts 104 | ADC1->SR = 0; 105 | 106 | DMA2_Stream0->NDTR = ADC_BUFFER_SIZE; 107 | 108 | CK_ADC_DMA_DMAStart(); 109 | CK_ADC_DMA_ADCStart(); 110 | 111 | } 112 | 113 | void CK_ADC_DMA_DMAStop(void){ 114 | 115 | DMA2_Stream0->CR &= ~(1u<<0); // DMA Stream stop 116 | 117 | } 118 | 119 | void CK_ADC_DMA_DMAStart(void){ 120 | 121 | DMA2_Stream0->CR |= (1u<<0); // DMA Stream start 122 | 123 | } 124 | 125 | void CK_ADC_DMA_ADCStop(void){ 126 | 127 | ADC1->CR2 &= ~(1u << 30); // Conversion stop, can only be set when adc is enabled 128 | } 129 | 130 | void CK_ADC_DMA_ADCStart(void){ 131 | 132 | ADC1->CR2 |= (1u << 30); // Conversion start, can only be set when adc is enabled 133 | } 134 | 135 | int CK_ADC_DMA_IsTxComplete(void){ 136 | 137 | return samplingIsCompleted; 138 | 139 | } 140 | 141 | void CK_ADC_DMA_TransferSamples(void){ 142 | 143 | #if DEBUG_TIMING 144 | uint32_t adc_tx_t1 = CK_TIME_GetMicroSec(); 145 | #endif 146 | 147 | uint16_t current_data = 0; 148 | uint8_t adc_lsb = 0; 149 | uint8_t adc_msb = 0; 150 | 151 | for(int i = 0; i < ADC_BUFFER_SIZE; i++){ 152 | 153 | current_data = adc_dma_buffer1[i]; 154 | 155 | #if TEST_MODE 156 | static uint32_t counter = 0; 157 | current_data = (uint16_t)counter++; 158 | if(counter == 65536) counter = 0; 159 | #endif 160 | 161 | adc_msb = (uint8_t)((current_data >> 8) & 0xFF); 162 | adc_lsb = (uint8_t)(current_data & 0xFF); 163 | 164 | CK_USBD_WriteTxCircularBuffer(adc_msb); 165 | CK_USBD_WriteTxCircularBuffer(adc_lsb); 166 | 167 | } 168 | 169 | #if DEBUG_TIMING 170 | uint32_t adc_tx_t2 = CK_TIME_GetMicroSec() - adc_tx_t1; 171 | adc_tx_t2++; 172 | 173 | uint32_t adc_tx_t3 = CK_TIME_GetMicroSec(); 174 | 175 | CK_USBD_Transmit(); 176 | 177 | uint32_t adc_tx_t4 = CK_TIME_GetMicroSec() - adc_tx_t3; 178 | UNUSED(adc_tx_t4); 179 | #else 180 | CK_USBD_Transmit(); 181 | #endif 182 | 183 | } 184 | 185 | void DMA2_Stream0_IRQHandler(void){ 186 | 187 | static int n1 = 0;UNUSED(n1); 188 | static int n2 = 0;UNUSED(n2); 189 | 190 | // For Stream0 Bit4 is Half Transfer Complete and Bit5 is Transfer Complete 191 | static uint32_t status = 0; 192 | status = DMA2->LISR; 193 | 194 | // DMA2 Stream0 Clear Interrupts 195 | DMA2->LIFCR = 0x3D << 0; 196 | 197 | // Half Transfer Complete 198 | if( ( ( status & (1u << 4) ) >> 4 ) == 1){ 199 | 200 | // I used these for debugging and it is working. 201 | // n1 is half size of DMA2_Stream0->NDTR 202 | n1 = DMA2_Stream0->NDTR; 203 | 204 | #if DEBUG_TIMING 205 | // For ADC_BUFFER_SIZE = 512 Half TX takes 492 microsecond 206 | adc_t2 = CK_TIME_GetMicroSec() - adc_t1; 207 | #endif 208 | } 209 | 210 | // Transfer Complete 211 | if( ( ( status & (1u << 5) ) >> 5 ) == 1){ 212 | 213 | // I used these for debugging and it is working. 214 | // n2 is 0 (NDTR is decremented after each dma trasnfer) 215 | n2 = DMA2_Stream0->NDTR; 216 | 217 | samplingIsCompleted = 1; 218 | 219 | #if DEBUG_TIMING 220 | // For ADC_BUFFER_SIZE = 512 Full TX takes 986 microsecond 221 | // 986 / 512 = 1.926 microsecond = Tsampling in ADC1->SMPR1, perfect. 222 | adc_t3 = CK_TIME_GetMicroSec() - adc_t1; 223 | 224 | CK_ADC_DMA_Start(); 225 | adc_t1 = CK_TIME_GetMicroSec(); 226 | #endif 227 | 228 | } 229 | 230 | } 231 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Frequency Modulated Continuous Wave Radar Hardware Design and the Firmware 2 | 3 | Check the new design's Python files for better processing and analysis https://github.com/ckflight/FMCW_RADAR_2v2 4 | 5 | #### Later Update 1: 6 | New version of the hardware is available in the **Radar 2** folder. For **Radar 2** design, two separated boards in **Radar MCU** and **Radar RF** folders are brought together with several necessary improvements. I recommend using the second design since it is more reliable and tested. The reason behind two separate board was to change digital part of the board without changing the RF part of it. However, one united design performs better and have a better temperature cooling control which affect the overall perfomance significantly. 7 | 8 | ##### Important Power Supply Note: I used switching regulator for 3.3 and 5V power sources to test their effect on the RF performance and oscillation of ripple voltage on OpAmp analog amplifier side. Therefore do not use switching regulator in your design. Change them to LDO type of clean supplies. Or add second LDO stage to the switching regulator unless you want an AM modulated ( 1.4 MHz switching freq. is very visible ) signal at the OpAmp side. After observing these affects i had to fine tune components which is not necessary if you use a cleaner source !!! 9 | 10 | #### Later Update 2: 11 | I have added a new Python script for plotting the radar data with Python Qt5 and Vispy plotting tool which uses GPU instead of CPU. Radar_Plot2.py is the source code. New code plots the time domain and frequency domain data together with scale and restart options. It has thread based approach between Vispy and Qt classes by using DataSource which allows us to manage more data. See first screenshot under Python Script Plots section below. 12 | 13 | #### Radar Info: 14 | * Frequency Modulated Continuous Wave Radar with 26 dBm output power covering around 250 meters range with 10 dBi gain patch antenna (400 meters in theory by using a better ADC with higher sampling rate to match the noise floor of the RF receiver chain). 15 | 16 | $$ Range(radar) = {\sqrt[4]{Pt * G^2 * \lambda^2 * \sigma \over Pmin * 4\pi^3}} $$ 17 | 18 | * Receiver chain has LNA, Gain Block and Mixer. The gain block drops the Noise Figure from 7 dB to 2 dB, which doubles the detection range. To determine the radar detection range, minimum detectable signal is needed. RF receiver chain has thermal noise and it determines the noise floor for Pmin. Signal to Noise (SNR) ratio of 20 dB is assumed for a good detectable signal then: 19 | 20 | $$ Pthermal(watt) = {k * T * B * F} $$ 21 | 22 | $$ Pthermal(dBm) = {10\log_{10} {kT \over 1mW} + NF + 10\log_{10} BW} $$ 23 | 24 | $$ Pmin(dBm) = {Pthermal(dBm) + 20dB} $$ 25 | 26 | 27 | * Radar, has an auto gain configuration with a digital potentiometer to control intermediate frequency (IF) signal gain at the last stage of the analog amplifier before sampling with ADC. 28 | 29 | * -40 dB / Decade Range Compensation Filter is implemented. Closer objects reflect more powerful RF signal which suppresses the signal of the objects at further distance. By amplifying the weaker signals and filtering the closer ones, each frequency band is adjusted to the same amplitude. 30 | 31 | * The IF signal is available at different stages of the amplifier and filter circuit for testing with other configurations. 32 | 33 | * The VCO range of the radar is from 5.5 to 6.1 GHz 34 | 35 | * Directional coupler has low insertion loss of 0.25 dB and 16 dB coupling. 36 | 37 | * ADF4158 Frequency Synthesizer is available due to the nonlinear characteristics of the VCO profile for accurate distance detection. ADF4158 can generate pulses with some gap between each sweep. During this gap samples are packed and buffered over USB. 38 | 39 | * STM32F4's DAC has a triangular waveform generation option and it can be used for VCO signal generation as well. Both option are available on board. Check schematic to populate necessary resistor values to use either mode. 40 | 41 | * SMA connector has 1 mm pad size, but the 50 Ohm transmission line is 0.342 mm wide. To prevent reflection, cutout is implemented beneath the SMA pad with CST Studio simulation which is also available at my repository https://github.com/ckflight/CST_ADS_MODELS_SIMULATIONS 42 | 43 | * PCB has 4 layers. 50 Ohm impedance microstrip transmission line is making 0.342mm trace width by using oshpark's stack-up below. Stack-up layer information can be found here: https://docs.oshpark.com/services/four-layer/ 44 | 45 | * Main loop runs with a Finite State Machine (FSM) to control radar, which checks the condition of the start of the sweep and the gap. ADF4158 Muxout is generating a pulse according to the sweep condition. External interrupt tracks this pulse to move between FSM states. 46 | 47 | * Hardware is configured using Python script so the PC is in Host mode and controls everything. In this way, any hardware parameters can be changed without reflashing the firmware. 48 | 49 | * N number of samples are determined by sweep bandwidth rise time and the sampling frequency. 50 | For example: 51 | 52 | Fs = 500.000 samples/sec and the sweep rise time is 1 millisecond (ms) for 200 MHz bandwidth. The system will pack 500 x 16 bit ADC samples and transfer 1000 x 8 bit ADC samples to Python script in 1 ms. Therefore, 1 MegaByte data is buffered to Host PC for 500 KHz sampling frequency in 1 second. 53 | 54 | * Python Script: I have uploaded an example record file along with python scripts where the peaks of the stationary objects can be seen. 55 | 56 | ### Object Type Detection: 57 | 58 | * Object type detection is done with the similar code that i wrote for my project at the repository https://github.com/ckflight/RADAR_24GHZ_NEURAL_NETWORK 59 | 60 | ## RADAR 2 Screenshot: 61 | ![Radar 2](https://user-images.githubusercontent.com/61315249/101276899-46bded00-37c1-11eb-818b-c42eb3b57e8a.png) 62 | 63 | ## RADAR 1 RF Board Screenshot: 64 | ![RADAR_RF](https://user-images.githubusercontent.com/61315249/82238636-4acb1000-9940-11ea-8323-65df61ffcf1b.png) 65 | 66 | ## RADAR 1 MCU Board Screenshot: 67 | ![RADAR_MCU](https://user-images.githubusercontent.com/61315249/82238631-47d01f80-9940-11ea-91dd-7cf658414dd1.png) 68 | 69 | ![IMG_20200511_111503](https://user-images.githubusercontent.com/61315249/81540098-d14c8400-9379-11ea-9681-371c4e8f2141.jpg) 70 | 71 | ## Python Script Plots: 72 | ![radar1](https://user-images.githubusercontent.com/61315249/213574328-27cf320e-f16c-410b-93ad-093b2bd386e1.png) 73 | 74 | ![radar2](https://user-images.githubusercontent.com/61315249/82351877-d8bcfe80-9a05-11ea-9fe4-1619731c1cea.png) 75 | 76 | ![radar3](https://user-images.githubusercontent.com/61315249/82351882-d9559500-9a05-11ea-9772-c6e71b53d2af.png) 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_cdc_if.c: -------------------------------------------------------------------------------- 1 | 2 | /* Includes ------------------------------------------------------------------*/ 3 | #include "usbd_cdc_if.h" 4 | #include "USBD_CDC/CK_USBD_INTERFACE.h" 5 | 6 | #define APP_RX_DATA_SIZE 2048 7 | #define APP_TX_DATA_SIZE 2048 8 | 9 | /* Create buffer for reception and transmission */ 10 | /* It's up to user to redefine and/or remove those define */ 11 | /** Received data over USB are stored in this buffer */ 12 | uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; 13 | 14 | /** Data to send over USB CDC are stored in this buffer */ 15 | uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; 16 | 17 | extern USBD_HandleTypeDef hUsbDeviceFS; 18 | 19 | static int8_t CDC_Init_FS(void); 20 | static int8_t CDC_DeInit_FS(void); 21 | static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length); 22 | static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len); 23 | 24 | /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ 25 | 26 | /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ 27 | 28 | USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = 29 | { 30 | CDC_Init_FS, 31 | CDC_DeInit_FS, 32 | CDC_Control_FS, 33 | CDC_Receive_FS 34 | }; 35 | 36 | /* Private functions ---------------------------------------------------------*/ 37 | /** 38 | * @brief Initializes the CDC media low layer over the FS USB IP 39 | * @retval USBD_OK if all operations are OK else USBD_FAIL 40 | */ 41 | static int8_t CDC_Init_FS(void) 42 | { 43 | /* USER CODE BEGIN 3 */ 44 | /* Set Application Buffers */ 45 | USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0); 46 | USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS); 47 | return (USBD_OK); 48 | /* USER CODE END 3 */ 49 | } 50 | 51 | /** 52 | * @brief DeInitializes the CDC media low layer 53 | * @retval USBD_OK if all operations are OK else USBD_FAIL 54 | */ 55 | static int8_t CDC_DeInit_FS(void) 56 | { 57 | /* USER CODE BEGIN 4 */ 58 | return (USBD_OK); 59 | /* USER CODE END 4 */ 60 | } 61 | 62 | /** 63 | * @brief Manage the CDC class requests 64 | * @param cmd: Command code 65 | * @param pbuf: Buffer containing command data (request parameters) 66 | * @param length: Number of data to be sent (in bytes) 67 | * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL 68 | */ 69 | static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) 70 | { 71 | /* USER CODE BEGIN 5 */ 72 | switch(cmd) 73 | { 74 | case CDC_SEND_ENCAPSULATED_COMMAND: 75 | 76 | break; 77 | 78 | case CDC_GET_ENCAPSULATED_RESPONSE: 79 | 80 | break; 81 | 82 | case CDC_SET_COMM_FEATURE: 83 | 84 | break; 85 | 86 | case CDC_GET_COMM_FEATURE: 87 | 88 | break; 89 | 90 | case CDC_CLEAR_COMM_FEATURE: 91 | 92 | break; 93 | 94 | /*******************************************************************************/ 95 | /* Line Coding Structure */ 96 | /*-----------------------------------------------------------------------------*/ 97 | /* Offset | Field | Size | Value | Description */ 98 | /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/ 99 | /* 4 | bCharFormat | 1 | Number | Stop bits */ 100 | /* 0 - 1 Stop bit */ 101 | /* 1 - 1.5 Stop bits */ 102 | /* 2 - 2 Stop bits */ 103 | /* 5 | bParityType | 1 | Number | Parity */ 104 | /* 0 - None */ 105 | /* 1 - Odd */ 106 | /* 2 - Even */ 107 | /* 3 - Mark */ 108 | /* 4 - Space */ 109 | /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ 110 | /*******************************************************************************/ 111 | case CDC_SET_LINE_CODING: 112 | 113 | break; 114 | 115 | case CDC_GET_LINE_CODING: 116 | 117 | break; 118 | 119 | case CDC_SET_CONTROL_LINE_STATE: 120 | 121 | break; 122 | 123 | case CDC_SEND_BREAK: 124 | 125 | break; 126 | 127 | default: 128 | break; 129 | } 130 | 131 | return (USBD_OK); 132 | /* USER CODE END 5 */ 133 | } 134 | 135 | /** 136 | * @brief Data received over USB OUT endpoint are sent over CDC interface 137 | * through this function. 138 | * 139 | * @note 140 | * This function will block any OUT packet reception on USB endpoint 141 | * untill exiting this function. If you exit this function before transfer 142 | * is complete on CDC interface (ie. using DMA controller) it will result 143 | * in receiving more data while previous ones are still not sent. 144 | * 145 | * @param Buf: Buffer of data to be received 146 | * @param Len: Number of data received (in bytes) 147 | * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL 148 | */ 149 | static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) 150 | { 151 | // Whenever data is received this method is called as well 152 | // so our code will save data to circular buffer here. 153 | 154 | /* USER CODE BEGIN 6 */ 155 | USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); 156 | 157 | USBD_CDC_ReceivePacket(&hUsbDeviceFS); 158 | 159 | CK_USBD_WriteRxCircularBuffer(&Buf[0], Len); 160 | 161 | return (USBD_OK); 162 | /* USER CODE END 6 */ 163 | } 164 | 165 | 166 | 167 | /** 168 | * @brief CDC_Transmit_FS 169 | * Data to send over USB IN endpoint are sent over CDC interface 170 | * through this function. 171 | * @note 172 | * 173 | * 174 | * @param Buf: Buffer of data to be sent 175 | * @param Len: Number of data to be sent (in bytes) 176 | * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY 177 | */ 178 | uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) 179 | { 180 | uint8_t result = USBD_OK; 181 | /* USER CODE BEGIN 7 */ 182 | USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; 183 | if (hcdc->TxState != 0){ 184 | return USBD_BUSY; 185 | } 186 | USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len); 187 | result = USBD_CDC_TransmitPacket(&hUsbDeviceFS); 188 | /* USER CODE END 7 */ 189 | return result; 190 | } 191 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/stm32f4xx_it.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f4xx_it.c 5 | * @brief Interrupt Service Routines. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2020 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | #include "stm32f4xx_hal.h" 23 | #include "stm32f4xx_it.h" 24 | /* Private includes ----------------------------------------------------------*/ 25 | /* USER CODE BEGIN Includes */ 26 | /* USER CODE END Includes */ 27 | 28 | /* Private typedef -----------------------------------------------------------*/ 29 | /* USER CODE BEGIN TD */ 30 | 31 | /* USER CODE END TD */ 32 | 33 | /* Private define ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN PD */ 35 | 36 | /* USER CODE END PD */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN PM */ 40 | 41 | /* USER CODE END PM */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | /* USER CODE BEGIN PV */ 45 | 46 | /* USER CODE END PV */ 47 | 48 | /* Private function prototypes -----------------------------------------------*/ 49 | /* USER CODE BEGIN PFP */ 50 | 51 | /* USER CODE END PFP */ 52 | 53 | /* Private user code ---------------------------------------------------------*/ 54 | /* USER CODE BEGIN 0 */ 55 | 56 | /* USER CODE END 0 */ 57 | 58 | /* External variables --------------------------------------------------------*/ 59 | 60 | /* USER CODE BEGIN EV */ 61 | 62 | /* USER CODE END EV */ 63 | 64 | extern PCD_HandleTypeDef hpcd_USB_OTG_FS; 65 | 66 | /******************************************************************************/ 67 | /* Cortex-M4 Processor Interruption and Exception Handlers */ 68 | /******************************************************************************/ 69 | /** 70 | * @brief This function handles Non maskable interrupt. 71 | */ 72 | void NMI_Handler(void) 73 | { 74 | /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ 75 | 76 | /* USER CODE END NonMaskableInt_IRQn 0 */ 77 | /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ 78 | 79 | /* USER CODE END NonMaskableInt_IRQn 1 */ 80 | } 81 | 82 | /** 83 | * @brief This function handles Hard fault interrupt. 84 | */ 85 | void HardFault_Handler(void) 86 | { 87 | /* USER CODE BEGIN HardFault_IRQn 0 */ 88 | 89 | /* USER CODE END HardFault_IRQn 0 */ 90 | while (1) 91 | { 92 | /* USER CODE BEGIN W1_HardFault_IRQn 0 */ 93 | /* USER CODE END W1_HardFault_IRQn 0 */ 94 | } 95 | } 96 | 97 | /** 98 | * @brief This function handles Memory management fault. 99 | */ 100 | void MemManage_Handler(void) 101 | { 102 | /* USER CODE BEGIN MemoryManagement_IRQn 0 */ 103 | 104 | /* USER CODE END MemoryManagement_IRQn 0 */ 105 | while (1) 106 | { 107 | /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ 108 | /* USER CODE END W1_MemoryManagement_IRQn 0 */ 109 | } 110 | } 111 | 112 | /** 113 | * @brief This function handles Pre-fetch fault, memory access fault. 114 | */ 115 | void BusFault_Handler(void) 116 | { 117 | /* USER CODE BEGIN BusFault_IRQn 0 */ 118 | 119 | /* USER CODE END BusFault_IRQn 0 */ 120 | while (1) 121 | { 122 | /* USER CODE BEGIN W1_BusFault_IRQn 0 */ 123 | /* USER CODE END W1_BusFault_IRQn 0 */ 124 | } 125 | } 126 | 127 | /** 128 | * @brief This function handles Undefined instruction or illegal state. 129 | */ 130 | void UsageFault_Handler(void) 131 | { 132 | /* USER CODE BEGIN UsageFault_IRQn 0 */ 133 | 134 | /* USER CODE END UsageFault_IRQn 0 */ 135 | while (1) 136 | { 137 | /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ 138 | /* USER CODE END W1_UsageFault_IRQn 0 */ 139 | } 140 | } 141 | 142 | /** 143 | * @brief This function handles System service call via SWI instruction. 144 | */ 145 | void SVC_Handler(void) 146 | { 147 | /* USER CODE BEGIN SVCall_IRQn 0 */ 148 | 149 | /* USER CODE END SVCall_IRQn 0 */ 150 | /* USER CODE BEGIN SVCall_IRQn 1 */ 151 | 152 | /* USER CODE END SVCall_IRQn 1 */ 153 | } 154 | 155 | /** 156 | * @brief This function handles Debug monitor. 157 | */ 158 | void DebugMon_Handler(void) 159 | { 160 | /* USER CODE BEGIN DebugMonitor_IRQn 0 */ 161 | 162 | /* USER CODE END DebugMonitor_IRQn 0 */ 163 | /* USER CODE BEGIN DebugMonitor_IRQn 1 */ 164 | 165 | /* USER CODE END DebugMonitor_IRQn 1 */ 166 | } 167 | 168 | /** 169 | * @brief This function handles Pendable request for system service. 170 | */ 171 | void PendSV_Handler(void) 172 | { 173 | /* USER CODE BEGIN PendSV_IRQn 0 */ 174 | 175 | /* USER CODE END PendSV_IRQn 0 */ 176 | /* USER CODE BEGIN PendSV_IRQn 1 */ 177 | 178 | /* USER CODE END PendSV_IRQn 1 */ 179 | } 180 | 181 | /** 182 | * @brief This function handles System tick timer. 183 | */ 184 | void SysTick_Handler(void) 185 | { 186 | /* USER CODE BEGIN SysTick_IRQn 0 */ 187 | 188 | /* USER CODE END SysTick_IRQn 0 */ 189 | HAL_IncTick(); 190 | /* USER CODE BEGIN SysTick_IRQn 1 */ 191 | 192 | /* USER CODE END SysTick_IRQn 1 */ 193 | } 194 | 195 | /******************************************************************************/ 196 | /* STM32F4xx Peripheral Interrupt Handlers */ 197 | /* Add here the Interrupt Handlers for the used peripherals. */ 198 | /* For the available peripheral interrupt handler names, */ 199 | /* please refer to the startup file (startup_stm32f4xx.s). */ 200 | /******************************************************************************/ 201 | 202 | /** 203 | * @brief This function handles USB On The Go FS global interrupt. 204 | */ 205 | void OTG_FS_IRQHandler(void) 206 | { 207 | /* USER CODE BEGIN OTG_FS_IRQn 0 */ 208 | 209 | /* USER CODE END OTG_FS_IRQn 0 */ 210 | HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); 211 | /* USER CODE BEGIN OTG_FS_IRQn 1 */ 212 | 213 | /* USER CODE END OTG_FS_IRQn 1 */ 214 | } 215 | 216 | /* USER CODE BEGIN 1 */ 217 | 218 | /* USER CODE END 1 */ 219 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 220 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_DAC.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_DAC.h" 3 | #include "CK_GPIO.h" 4 | #include "CK_TIME_HAL.h" 5 | 6 | 7 | // DAC's internal triangle waveform generator is used 8 | #define DAC_WAVEFORM_GENERATE 9 | 10 | #define DAC_OUT_GPIO GPIOA 11 | #define DAC_OUT_PIN 4 12 | 13 | 14 | #define DAC_START 0 //2072 15 | #define DAC_END 4095 //3438 16 | 17 | 18 | uint16_t dac_counter = DAC_START; 19 | 20 | int dac_count_way = 1; 21 | 22 | RAMP_TYPE selected_ramp; 23 | 24 | /* 25 | * NOTES: 26 | * Triangular is better compared to sawtooth in fast vehicle detection 27 | * and for rest they are almost same in Radar's perspective. 28 | * Also in triangular mode, i do not need to know if waveform period is done since 29 | * it will count down so if 6GHz is send 5.9GHz will be mixed not start freq. of 5.6GHz 30 | * Also STM32F405 has internal TRIANGLE generator reaching 400microsecond period 31 | * without disturbing the code with MHz level interrupts. 32 | * 33 | */ 34 | 35 | void CK_DAC_Init(RAMP_TYPE ramp){ 36 | 37 | selected_ramp = ramp; 38 | 39 | // PA4 DAC_OUT1 40 | // Clock is enabled by GPIO Init function 41 | 42 | // APB1ENR TIM6 4th bit, DAC 29th bit 43 | RCC->APB1ENR |= (1u << 29); 44 | 45 | GPIOA->MODER |= (3u << 8); // pin 4 is in analog mode. 46 | //GPIOA->MODER |= (3u << 10); // pin 5 is in analog mode. 47 | 48 | #if defined(DAC_WAVEFORM_GENERATE) 49 | // DAC Trigger enable, software trigger selected, output buffer is enabled default 50 | // Triangle generator setup number bigger than 11 to max aplitude of 3.3v (bit 24-27) 51 | // Triangle generation 2u to bits 22-23 52 | // Trigger enable for waveform generation bit 18 53 | // Trigger select is software bits 19-21 (Conversion starts with SWTRIG bit) 54 | // Internal counter will be incremented after each trigger event 55 | // Bit17 is output buffer enabled. 56 | // Timer7 trigger TRGO event is selected for TSEL bits 57 | // I select Update event in timer7 cr2 register 58 | // Now triangle is auto generated internally by timer7 pulses 59 | // And it can be as fast as APB1 clock speed 60 | 61 | //DAC1 62 | // 5.7 to 5.9 GHZ range will be used. HMC431 generates 5 to 6.2 GHz range 63 | // 5.7 GHz -> 3V(HMC431 Datasheet) -> 3V / 3 = 1V -> (4096 * 1V) / 3.3V = 1241 is start value of DAC 64 | // 5.9 GHz -> 5V(HMC431 Datasheet) -> 5V / 3 = 1.65V -> (4096 * 1.65V) / 3.3V = 2047 is end value of DAC 65 | // Set MAMP1 is max value internal counter reaches. 66 | // Internal counter is added to DHR value and output voltage is generated. 67 | // 7u << 8 is 255 max for counter with 1650 for start value. I will generate 100 MHz 68 | // from 5.8 to 5.9GHz. In this way it might have a better resolution for short distance. 69 | DAC->CR |= (7u << 8) | (2u << 6) | (2u << 3) | (1u << 2) | (1u << 1); 70 | 71 | DAC->DHR12R1 = 1650; 72 | 73 | //DAC2 for testing not implemented on hardware!!! 74 | //DAC->CR |= (12u << 24) | (2u << 22) | (2u << 19) | (1u << 18) | (1u << 17); 75 | 76 | #else 77 | // DAC Trigger enable, software trigger selected, output buffer is enabled default 78 | // DAC1 79 | DAC->CR |= (1u << 1) | (1u << 2) | (7u << 3); 80 | 81 | // DAC2 82 | //DAC->CR |= (1u << 17) | (1u << 18) | (7u << 19); 83 | #endif 84 | 85 | // Enable DAC1 86 | DAC->CR |= (1u<<0); 87 | 88 | // Enable DAC2 89 | //DAC->CR |= (1u<<16); 90 | 91 | CK_DAC_TIMER_Init(); 92 | 93 | } 94 | 95 | void CK_DAC_TIMER_Init(void){ 96 | 97 | // APB1ENR TIM6 4th bit, TIM7 5th bit, TIM5 3th bit 98 | // APB1 42MHz x 2 = Timer Clock 84MHz 99 | RCC->APB1ENR |= (1u << 5); 100 | 101 | /* Reference manual p.153 102 | * If the APB prescaler is configured to a division factor of 1, 103 | * the timer clock frequencies (TIMxCLK) are set to PCLKx. 104 | * Otherwise, the timer clock frequencies are twice the frequency of the 105 | * APB domain to which the timers are connected: TIMxCLK = 2xPCLKx. 106 | */ 107 | 108 | #if defined(DAC_WAVEFORM_GENERATE) 109 | // In triangle waveform usage ARR and PSC can be set for max speed 110 | // where triangle period is down to 400 microsec at max with PSC = 0 and ARR = 1 111 | 112 | // CLK = TimerClkb(84MHz) / (PSC + 1) 113 | // Some measured settings: 114 | // PSC 1, ARR 84 -> 4.4ms period for 3V to 5V range (looks good on scope fft) 115 | // PSC 2, ARR 84 -> 6.4ms period for 3V to 5V range 116 | // PSC 4, ARR 168 -> 20ms period for 3V to 5V range 117 | // PSC 4, ARR 336 -> 40ms period for 3V to 5V range (MIT Radar is using 40ms) 118 | // Low period work better. 119 | TIM7->PSC = 1; 120 | TIM7->ARR = 336; 121 | 122 | // Master mode selection for TRGO event for DAC 123 | // Update event is selected 124 | TIM7->CR2 |= (2u << 4); 125 | 126 | #else 127 | // CLK = TimerClkb(84MHz) / (PSC + 1) 128 | TIM7->PSC = 1; 129 | 130 | // 84 is minimum can be set without disturbing the code with interrupt 131 | // And it cannot reach higher speed even if for example 42 is set. 132 | TIM7->ARR = 84; // 84 for 2microsec interrupt 133 | 134 | HAL_NVIC_EnableIRQ(TIM7_IRQn); 135 | 136 | #endif 137 | 138 | // Update generate 139 | TIM7->EGR |= (1u << 0); 140 | 141 | // Auto reload enable, update source 142 | TIM7->CR1 |= (1u << 7) | (1u << 2); 143 | 144 | // update interrupt enabled 145 | TIM7->DIER |= 1u << 0; 146 | 147 | // counter enable 148 | TIM7->CR1 |= (1u <<0); 149 | 150 | } 151 | 152 | void CK_DAC_LoadValue(uint16_t value){ 153 | 154 | // DAC1 right alligned 12bit data register 155 | DAC->DHR12R1 = value & 0x0FFF; 156 | DAC->DHR12R2 = value & 0x0FFF; 157 | 158 | // Software trigger to start conversion 159 | // DHR value is loaded to DORx after 3 APB1 clocks 160 | // this bit is cleared auto after conversion 161 | DAC->SWTRIGR |= 1u<<0; // soft. trig dac1 162 | DAC->SWTRIGR |= 1u<<1; // soft. trig dac2 163 | 164 | } 165 | 166 | void CK_DAC_Sawtooth(void){ 167 | 168 | if(dac_counter == DAC_END){ 169 | dac_counter = DAC_START; 170 | } 171 | else{ 172 | dac_counter++; 173 | } 174 | 175 | CK_DAC_LoadValue(dac_counter); 176 | 177 | } 178 | 179 | void CK_DAC_Triangular(void){ 180 | 181 | if(dac_count_way == 1){ 182 | if(dac_counter == DAC_END){ 183 | dac_count_way = 0; 184 | } 185 | else{ 186 | dac_counter++; 187 | } 188 | } 189 | else{ 190 | if(dac_counter == DAC_START){ 191 | dac_count_way = 1; 192 | } 193 | else{ 194 | dac_counter--; 195 | } 196 | } 197 | 198 | CK_DAC_LoadValue(dac_counter); 199 | } 200 | 201 | #if defined(DAC_WAVEFORM_GENERATE) 202 | void TIM7_IRQHandler(void){ 203 | 204 | // For triangle generation of software trigger this must be done. 205 | // Will not use soft. trigger for waveform generation. 206 | //DAC->SWTRIGR |= 1u<<1; // soft. trig dac2 207 | TIM7->SR = 0; 208 | 209 | } 210 | #else 211 | 212 | // If DAC will be driven manually with software trigger. 213 | void TIM7_IRQHandler(void){ 214 | 215 | uint32_t status = TIM7->SR; 216 | 217 | if(status == 1){ 218 | 219 | // This part for detecting DAC timer frequency. 220 | /* 221 | static int count = 0; 222 | if(count == 0){ 223 | dac_timer_t1 = CK_TIME_GetMicroSec(); 224 | count = 1; 225 | } 226 | else{ 227 | dac_timer_t2 = CK_TIME_GetMicroSec() - dac_timer_t1; 228 | count = 0; 229 | } 230 | */ 231 | 232 | if(selected_ramp == TRIANGULAR_WAVEFORM_DAC){ 233 | CK_DAC_Triangular(); 234 | } 235 | else if(selected_ramp == SAWTOOTH_WAVEFORM_DAC){ 236 | CK_DAC_Sawtooth(); 237 | } 238 | 239 | TIM7->SR = 0; 240 | 241 | } 242 | 243 | } 244 | 245 | #endif 246 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_UART.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_UART.h" 3 | #include "CK_GPIO.h" 4 | 5 | 6 | void CK_UART_Init1(int baudRate){ 7 | 8 | /* 9 | * Default 8bit 1 start 1 stop bit, no parity 10 | * USART1,6 Clocked by PCLK2 11 | * USART2,3,4,5 Clocked by PCLK1 12 | */ 13 | int baud = baudRate; 14 | 15 | int frequency_pclk2 = HAL_RCC_GetPCLK2Freq();//90MHz or 84MHz 16 | frequency_pclk2 = 90000000;//90MHz or 84MHz 17 | 18 | int baudNum = frequency_pclk2/(8*baud); 19 | 20 | /* 21 | * USART1 PA9=TX,PA10=RX 22 | * RX Not Used 23 | */ 24 | RCC->APB2ENR |= CK_RCC_APB2ENR_USART1; 25 | CK_GPIO_ClockEnable(GPIOA); 26 | CK_GPIO_Init(GPIOA,9,CK_GPIO_AF,CK_GPIO_AF7,CK_GPIO_PUSHPULL,CK_GPIO_HIGH,CK_GPIO_NOPUPD); 27 | CK_GPIO_Init(GPIOA,10,CK_GPIO_AF,CK_GPIO_AF7,CK_GPIO_PUSHPULL,CK_GPIO_HIGH,CK_GPIO_NOPUPD); 28 | 29 | USART1->BRR = baudNum<<4;//First 4 bit is fraction and not affecting 30 | USART1->CR1 |= CK_USART_CR1_UE | CK_USART_CR1_OVER8; 31 | 32 | } 33 | 34 | void CK_Usart1Send(uint8_t chr[],int size){ 35 | 36 | USART1->CR1 |= CK_USART_CR1_TE; 37 | for(int i=0;iDR = chr[i]; 39 | while((USART1->SR & CK_USART_SR_TXE) == 0); 40 | } 41 | while((USART1->SR & CK_USART_SR_TC) == 0); 42 | } 43 | 44 | void CK_IntPrintln(int num){ 45 | int idx = 0; 46 | if(num < 0){ 47 | CK_TXBuffer_int[idx++] = 45;//ASCII '-' 48 | num *= -1; 49 | } 50 | int tmp[6]; 51 | int numOfDigits = 0; 52 | int limit = 6; 53 | 54 | for(int i=0; i < limit; i++){ 55 | if(num>=10){ 56 | tmp[i] = (int)num%10; 57 | num = num-tmp[i]; 58 | num = num/10; 59 | } 60 | else{ 61 | tmp[i] = num; 62 | numOfDigits = i; 63 | i = limit; 64 | } 65 | } 66 | for(int i=numOfDigits; i >= 0; i--){ 67 | CK_TXBuffer_int[idx++] = tmp[i]+48;//for ASCII code of number 68 | } 69 | CK_TXBuffer_int[idx++] = 0x0A; //ASCII line feed 70 | CK_TXBuffer_int[idx++] = 0x0D; //ASCII carriage return 71 | 72 | 73 | CK_Usart1Send(CK_TXBuffer_int,idx); 74 | 75 | } 76 | 77 | void CK_IntPrint(int num){ 78 | int idx = 0; 79 | if(num < 0){ 80 | CK_TXBuffer_int[idx++] = 45;//ASCII '-' 81 | num *= -1; 82 | } 83 | int tmp[6]; 84 | int numOfDigits = 0; 85 | int limit = 6; 86 | 87 | for(int i=0; i < limit; i++){ 88 | if(num>=10){ 89 | tmp[i] = (int)num%10; 90 | num = num-tmp[i]; 91 | num = num/10; 92 | } 93 | else{ 94 | tmp[i] = num; 95 | numOfDigits = i; 96 | i = limit; 97 | } 98 | } 99 | for(int i=numOfDigits; i >= 0; i--){ 100 | CK_TXBuffer_int[idx++] = tmp[i]+48;//for ASCII code of number 101 | } 102 | 103 | CK_Usart1Send(CK_TXBuffer_int,idx); 104 | 105 | } 106 | 107 | void CK_Int16Println(int16_t num){ 108 | int idx = 0; 109 | int16_t numUnsigned = num; 110 | if(num < 0){ 111 | CK_TXBuffer_int16[idx++] = 45;//ASCII '-' 112 | numUnsigned = ~(num) + 1; //2's Complement 113 | } 114 | int tmp[6]; 115 | int numOfDigits = 0; 116 | int limit = 6; 117 | 118 | 119 | for(int i=0; i < limit; i++){ 120 | if(numUnsigned>=10){ 121 | tmp[i] = (int)numUnsigned%10; 122 | numUnsigned = numUnsigned-tmp[i]; 123 | numUnsigned = numUnsigned/10; 124 | } 125 | else{ 126 | tmp[i] = numUnsigned; 127 | numOfDigits = i; 128 | i = limit; 129 | } 130 | } 131 | for(int i=numOfDigits; i >= 0; i--){ 132 | CK_TXBuffer_int16[idx++] = tmp[i]+48;//for ASCII code of number 133 | } 134 | CK_TXBuffer_int16[idx++] = 10;//ASCII new line 135 | 136 | CK_Usart1Send(CK_TXBuffer_int16,idx); 137 | 138 | } 139 | 140 | void CK_Int16Print(int16_t num){ 141 | int idx = 0; 142 | int16_t numUnsigned = num; 143 | if(num < 0){ 144 | CK_TXBuffer_int16[idx++] = 45;//ASCII '-' 145 | numUnsigned = ~(num) + 1; //2's Complement 146 | } 147 | int tmp[6]; 148 | int numOfDigits = 0; 149 | int limit = 6; 150 | 151 | 152 | for(int i=0; i < limit; i++){ 153 | if(numUnsigned>=10){ 154 | tmp[i] = (int)numUnsigned%10; 155 | numUnsigned = numUnsigned-tmp[i]; 156 | numUnsigned = numUnsigned/10; 157 | } 158 | else{ 159 | tmp[i] = numUnsigned; 160 | numOfDigits = i; 161 | i = limit; 162 | } 163 | } 164 | for(int i=numOfDigits; i >= 0; i--){ 165 | CK_TXBuffer_int16[idx++] = tmp[i]+48;//for ASCII code of number 166 | } 167 | 168 | CK_Usart1Send(CK_TXBuffer_int16,idx); 169 | 170 | } 171 | 172 | void CK_FloatPrintln(float num){ 173 | int idx = 0; 174 | int flag = 0; 175 | num = num*100;//2 digit after comma 176 | int intnum = (int)num; 177 | const int limit = 10;//10 digit number max 178 | if(intnum<0){ 179 | CK_TXBuffer_float[idx++] = 45;//ASCII '-' 180 | intnum *= -1; 181 | } 182 | if(intnum<10){//0.00 183 | flag = 1; 184 | } 185 | else if(intnum>=10 && intnum<=99){//0.01 to 0.99 186 | flag = 2; 187 | } 188 | 189 | int tmp[limit]; 190 | int numOfDigits = 0; 191 | for(int i=0;i=10){ 193 | tmp[i] = (int)intnum%10; 194 | intnum = intnum-tmp[i]; 195 | intnum = intnum/10; 196 | } 197 | else{ 198 | tmp[i] = intnum; 199 | numOfDigits = i;//get num of digits 200 | i = limit;//end loop 201 | } 202 | } 203 | if(flag==1){//make 0.00 204 | tmp[1] = 0;tmp[2] = 0; 205 | numOfDigits = 2; 206 | } 207 | if(flag==2){//add 0 for 0.01 to 0.99 numbers 208 | tmp[++numOfDigits] = 0; 209 | } 210 | 211 | for(int i=numOfDigits; i >= 0; i--){ 212 | if(i>1){ 213 | CK_TXBuffer_float[idx++] = tmp[i]+48;//for ASCII code of number 214 | } 215 | else if(i==1){ 216 | CK_TXBuffer_float[idx++] = 46;//for ASCII code of '.' 217 | CK_TXBuffer_float[idx++] = tmp[i]+48;//for ASCII code of number 218 | } 219 | else{ 220 | CK_TXBuffer_float[idx++] = tmp[i]+48;//for ASCII code of number 221 | } 222 | } 223 | CK_TXBuffer_float[idx++] = 10;//ASCII new line 224 | CK_Usart1Send(CK_TXBuffer_float,idx); 225 | 226 | } 227 | 228 | void CK_FloatPrint(float num){ 229 | int idx = 0; 230 | int flag = 0; 231 | num = num*100;//2 digit after comma 232 | int intnum = (int)num; 233 | const int limit = 10;//10 digit number max 234 | if(intnum<0){ 235 | CK_TXBuffer_float[idx++] = 45;//ASCII '-' 236 | intnum *= -1; 237 | } 238 | if(intnum<10){//0.00 239 | flag = 1; 240 | } 241 | else if(intnum>=10 && intnum<=99){//0.01 to 0.99 242 | flag = 2; 243 | } 244 | 245 | int tmp[limit]; 246 | int numOfDigits = 0; 247 | for(int i=0;i=10){ 249 | tmp[i] = (int)intnum%10; 250 | intnum = intnum-tmp[i]; 251 | intnum = intnum/10; 252 | } 253 | else{ 254 | tmp[i] = intnum; 255 | numOfDigits = i;//get num of digits 256 | i = limit;//end loop 257 | } 258 | } 259 | if(flag==1){//make 0.00 260 | tmp[1] = 0;tmp[2] = 0; 261 | numOfDigits = 2; 262 | } 263 | if(flag==2){//add 0 for 0.01 to 0.99 numbers 264 | tmp[++numOfDigits] = 0; 265 | } 266 | 267 | for(int i=numOfDigits; i >= 0; i--){ 268 | if(i>1){ 269 | CK_TXBuffer_float[idx++] = tmp[i]+48;//for ASCII code of number 270 | } 271 | else if(i==1){ 272 | CK_TXBuffer_float[idx++] = 46;//for ASCII code of '.' 273 | CK_TXBuffer_float[idx++] = tmp[i]+48;//for ASCII code of number 274 | } 275 | else{ 276 | CK_TXBuffer_float[idx++] = tmp[i]+48;//for ASCII code of number 277 | } 278 | } 279 | CK_Usart1Send(CK_TXBuffer_float,idx); 280 | 281 | } 282 | 283 | void CK_StringPrintln(const char str[]){ 284 | 285 | int size = CK_getArraySize(str); 286 | uint8_t tmp[CK_BufferSize]; 287 | for(int i=0;i 1.67 to 2.77 24 | * so DAC range is from 2072 to 3438. 25 | * Approximately 1 microsecond timer update is necessary. 26 | * 27 | * Hardware parameters are configured by python script at the beginning of radar measurement. 28 | * 29 | * Radar range: 30 | * Distance = (c * Ts * Fif) / (2 * B) 31 | * Apprx. 500meters = (3*10^8 * 1*10^-3 * 500*10^3) / (2 * 200 * 10^6) 32 | * 33 | */ 34 | 35 | #define MIXER_EN_GPIO GPIOA 36 | #define MIXER_EN_PIN 0 37 | 38 | #define SYNC_SIGNAL_GPIO GPIOB 39 | #define SYNC_SIGNAL_PIN 9 40 | 41 | #define FPGA_MODE 0 42 | 43 | uint32_t RECORD_TIME_COUNTER = 10000; // default 44 | uint8_t TX_MODE = 0; // 0 for continuous tx, 1 for on off with tx 45 | uint8_t DATA_LOG = 0; // 0 for USB Transfer, 1 for Microcard Log 46 | uint8_t ADC_SELECT = 0; // 0 for ADC DMA, 1 for External ADC MAX1426 47 | uint8_t PLL_SELECT = 1; // 0 for DAC, 1 for PLL 48 | 49 | uint32_t record_counter = 0; 50 | 51 | int isRestarted = 0; 52 | 53 | 54 | typedef enum{ 55 | 56 | IDLE, 57 | START_SAMPLING, 58 | CHECK_SAMPLING, 59 | TRANSFER_SAMPLES, 60 | FINISH_SAMPLING 61 | 62 | }SAMPLING_STATES_E; 63 | 64 | SAMPLING_STATES_E sampling_state = IDLE; 65 | 66 | int main(void){ 67 | 68 | CK_SYSTEM_SetSystemClock(SYSTEM_CLK_168MHz); 69 | 70 | HAL_Init(); 71 | 72 | CK_GPIO_ClockEnable(GPIOA); 73 | CK_GPIO_ClockEnable(GPIOB); 74 | CK_GPIO_ClockEnable(GPIOC); 75 | CK_GPIO_ClockEnable(GPIOD); 76 | 77 | /* 78 | * PA0 -> MIXER_EN, Enables or disables bias circuit and the internal detector. 79 | * See datasheet pg28 bias circuit. Use pull high 80 | */ 81 | CK_GPIO_Init(MIXER_EN_GPIO, MIXER_EN_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 82 | CK_GPIO_SetPin(MIXER_EN_GPIO, MIXER_EN_PIN); 83 | 84 | /* 85 | * Sync pulse is used to check if sampling and usb transfer is occurring before 86 | * muxout so ramp timings. Use scope to check state machine. 87 | */ 88 | CK_GPIO_Init(SYNC_SIGNAL_GPIO, SYNC_SIGNAL_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 89 | CK_GPIO_ClearPin(SYNC_SIGNAL_GPIO, SYNC_SIGNAL_PIN); 90 | 91 | CK_USBD_Init(); 92 | 93 | // adc uses it pin 94 | //MCP4022_Init(); 95 | 96 | CK_TQP5523_Init(); // Start before configuration 97 | 98 | CK_CONFIGURATION_InitHardware(1); // 1 receive python, 2 default values for debugging, 3 for fpga 99 | 100 | RECORD_TIME_COUNTER = CK_CONFIGURATION_GetRecordTimeCounter(); 101 | 102 | TX_MODE = CK_CONFIGURATION_GetTXMode(); 103 | 104 | DATA_LOG = CK_CONFIGURATION_GetDataLog(); 105 | 106 | ADC_SELECT = CK_CONFIGURATION_GetAdcSelect(); 107 | 108 | PLL_SELECT = CK_CONFIGURATION_GetPLLSelect(); 109 | 110 | uint8_t gain_value = CK_CONFIGURATION_GetGainValue(); 111 | 112 | 113 | if(DATA_LOG == 1){ 114 | CK_MICROCARD_Init(SPI_DMA_INTERRUPT_MULTIBLOCK); 115 | } 116 | 117 | //MCP4022_SetValue(gain_value); 118 | 119 | if(PLL_SELECT == 1){ 120 | CK_ADF4158_Init(SAWTOOTH_WAVEFORM); 121 | } 122 | else{ 123 | CK_DAC_Init(SAWTOOTH_WAVEFORM_DAC); 124 | } 125 | 126 | if(ADC_SELECT == 1){ 127 | CK_MAX1426_Init(); 128 | } 129 | else{ 130 | CK_ADC_DMA_Init(); 131 | } 132 | 133 | while(1){ 134 | 135 | #if FPGA_MODE 136 | 137 | static int is_system_started = 0; 138 | 139 | if(!is_system_started){ 140 | 141 | CK_TQP5523_Enable(); 142 | 143 | uint8_t record_time = CK_CONFIGURATION_GetRecordTime(); 144 | 145 | for(int i = 0; i < record_time * 1000; i++){ 146 | 147 | CK_TIME_DelayMicroSec(1000); 148 | 149 | } 150 | 151 | CK_TQP5523_Disable(); 152 | 153 | is_system_started = 1; 154 | 155 | } 156 | 157 | 158 | #else 159 | 160 | switch(sampling_state){ 161 | 162 | case IDLE: 163 | 164 | if(TX_MODE == 0){ 165 | CK_TQP5523_Enable(); 166 | } 167 | 168 | sampling_state = START_SAMPLING; 169 | 170 | break; 171 | 172 | case START_SAMPLING: 173 | 174 | if(CK_ADF4158_RampCompleted() == 0 && CK_ADF4158_RampStarted() == 1){ 175 | 176 | if(TX_MODE == 1){ 177 | CK_TQP5523_Enable(); 178 | } 179 | 180 | if(ADC_SELECT == 1){ 181 | 182 | CK_MAX1426_Reset_Counter(); 183 | CK_MAX1426_ResetRecordDone(); 184 | CK_MAX1426_ADC_OutputEnable(); 185 | CK_MAX1426_PWM_Start(); 186 | 187 | } 188 | else{ 189 | 190 | // Start sampling 191 | CK_ADC_DMA_Start(); 192 | 193 | } 194 | 195 | sampling_state = CHECK_SAMPLING; 196 | 197 | // Use these pulse to check sync with muxout. 198 | CK_GPIO_ClearPin(SYNC_SIGNAL_GPIO, SYNC_SIGNAL_PIN); 199 | 200 | } 201 | 202 | break; 203 | 204 | case CHECK_SAMPLING: 205 | 206 | if(ADC_SELECT == 1){ 207 | 208 | // Check is buffer full 209 | if(CK_MAX1426_IsRecordDone() == 1){ 210 | 211 | if(TX_MODE == 1){ 212 | CK_TQP5523_Disable(); 213 | } 214 | 215 | CK_MAX1426_ADC_OutputDisable(); 216 | CK_MAX1426_PWM_Stop(); 217 | 218 | sampling_state = TRANSFER_SAMPLES; 219 | 220 | } 221 | 222 | } 223 | else{ 224 | 225 | // Check full dma transfer is completed 226 | if(CK_ADC_DMA_IsTxComplete() == 1){ 227 | 228 | if(TX_MODE == 1){ 229 | CK_TQP5523_Disable(); 230 | } 231 | 232 | // DMA is not in circular mode so it stops automatically after NDTR transfers 233 | 234 | // Use these pulse to check sync with muxout. 235 | CK_GPIO_SetPin(SYNC_SIGNAL_GPIO, SYNC_SIGNAL_PIN); 236 | 237 | sampling_state = TRANSFER_SAMPLES; 238 | } 239 | } 240 | 241 | break; 242 | 243 | case TRANSFER_SAMPLES: 244 | 245 | if(CK_ADF4158_RampCompleted() == 1 && CK_ADF4158_RampStarted() == 0){ 246 | 247 | if(DATA_LOG == 0){ 248 | 249 | if(record_counter < RECORD_TIME_COUNTER){ 250 | 251 | record_counter++; 252 | 253 | CK_GPIO_ClearPin(SYNC_SIGNAL_GPIO, SYNC_SIGNAL_PIN); 254 | 255 | if(ADC_SELECT == 1){ 256 | CK_MAX1426_TransferSamplesUSB(); 257 | } 258 | else{ 259 | CK_ADC_DMA_TransferSamplesUSB(); 260 | } 261 | 262 | 263 | CK_GPIO_SetPin(SYNC_SIGNAL_GPIO, SYNC_SIGNAL_PIN); 264 | 265 | sampling_state = START_SAMPLING; 266 | 267 | } 268 | else{ 269 | 270 | if(TX_MODE == 0){ 271 | CK_TQP5523_Disable(); 272 | } 273 | 274 | sampling_state = FINISH_SAMPLING; 275 | } 276 | 277 | } 278 | else{ 279 | 280 | if(!CK_MICROCARD_IsCompleted()){ 281 | 282 | CK_GPIO_ClearPin(SYNC_SIGNAL_GPIO, SYNC_SIGNAL_PIN); 283 | 284 | if(ADC_SELECT == 1){ 285 | CK_MAX1426_TransferSamplesMicroCard(); 286 | } 287 | else{ 288 | // Implement microcard log for adc dma 289 | } 290 | 291 | CK_GPIO_SetPin(SYNC_SIGNAL_GPIO, SYNC_SIGNAL_PIN); 292 | 293 | sampling_state = START_SAMPLING; 294 | 295 | } 296 | 297 | else{ 298 | 299 | if(TX_MODE == 0){ 300 | CK_TQP5523_Disable(); 301 | } 302 | 303 | sampling_state = FINISH_SAMPLING; 304 | } 305 | 306 | } 307 | 308 | } 309 | 310 | break; 311 | 312 | case FINISH_SAMPLING: 313 | 314 | NVIC_SystemReset(); 315 | 316 | break; 317 | 318 | } 319 | 320 | 321 | #endif 322 | 323 | 324 | } 325 | 326 | } 327 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_SPI.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_GPIO.h" 3 | #include "CK_SPI.h" 4 | 5 | #define CK_SPIx_CR1_MSTR 1u<<2 6 | #define CK_SPIx_CR1_CPOL 1u<<1 7 | #define CK_SPIx_CR1_CPHA 1u<<0 8 | #define CK_SPIx_CR1_SPE 1u<<6 9 | #define CK_SPIx_CR1_SSI 1u<<8 10 | #define CK_SPIx_CR1_SSM 1u<<9 11 | 12 | #define CK_SPIx_CR2_TXDMAEN 1u<<1 13 | #define CK_SPIx_CR2_RXDMAEN 1u<<0 14 | 15 | #define CK_SPIx_SR_TXE 1u<<1 16 | #define CK_SPIx_SR_RXNE 1u<<0 17 | #define CK_SPIx_SR_BSY 1u<<7 18 | 19 | #define CK_RCC_SPI1_EN 1u<<12 20 | #define CK_RCC_SPI2_EN 1u<<14 21 | #define CK_RCC_SPI3_EN 1u<<15 22 | #define CK_RCC_SPI5_EN 1u<<20 23 | 24 | 25 | #define SPI_TIMEOUT 250 // 250 makes around 25 usec which is enough. 26 | 27 | typedef struct{ 28 | 29 | uint32_t timeout; 30 | 31 | uint32_t spi1_timeout; 32 | int spi1_init; 33 | 34 | uint32_t spi2_timeout; 35 | int spi2_init; 36 | 37 | uint32_t spi3_timeout; 38 | int spi3_init; 39 | 40 | uint32_t spi5_timeout; 41 | int spi5_init; 42 | 43 | }SPI_t; 44 | 45 | SPI_t spi_variables = { 46 | 47 | .timeout = 0, 48 | 49 | .spi1_timeout = 0, 50 | .spi1_init = 0, 51 | 52 | .spi2_timeout = 0, 53 | .spi2_init = 0, 54 | 55 | .spi3_timeout = 0, 56 | .spi3_init = 0, 57 | 58 | .spi5_timeout = 0, 59 | .spi5_init = 0, 60 | 61 | }; 62 | 63 | void CK_SPI_Init(SPI_TypeDef* spi_n){ 64 | 65 | SPI_TypeDef* SPIx = spi_n; 66 | GPIO_TypeDef* GPIOx; 67 | CK_GPIOx_AFx AFx; 68 | uint16_t miso_pin, mosi_pin, sck_pin; 69 | 70 | /* 71 | * SPI1,4,5 have APB2 = 90MHz 72 | * SPI2 have APB1 = 45MHz 73 | * so prescaler must be selected to meet 10MHZ max spi clock speed 74 | * 75 | */ 76 | 77 | if(SPIx == SPI1){ 78 | 79 | GPIOx = GPIOA; 80 | 81 | sck_pin = 5; 82 | miso_pin = 6; 83 | mosi_pin = 7; 84 | 85 | AFx = CK_GPIO_AF5; 86 | RCC->APB2ENR |= CK_RCC_SPI1_EN; // Enable related SPI clock 87 | 88 | spi_variables.spi1_init = 1; 89 | spi_variables.spi1_timeout = 0; 90 | } 91 | else if(SPIx == SPI2){ 92 | 93 | GPIOx = GPIOB; 94 | 95 | sck_pin = 13; 96 | miso_pin = 14; 97 | mosi_pin = 15; 98 | 99 | AFx = CK_GPIO_AF5; 100 | RCC->APB1ENR |= CK_RCC_SPI2_EN; // Enable related SPI clock 101 | 102 | spi_variables.spi2_init = 1; 103 | spi_variables.spi2_timeout = 0; 104 | } 105 | else if(SPIx == SPI3){ 106 | 107 | GPIOx = GPIOC; 108 | 109 | sck_pin = 10; 110 | miso_pin = 11; 111 | mosi_pin = 12; 112 | 113 | AFx = CK_GPIO_AF6; 114 | RCC->APB1ENR |= CK_RCC_SPI3_EN; // Enable related SPI clock 115 | 116 | spi_variables.spi3_init = 1; 117 | spi_variables.spi3_timeout = 0; 118 | } 119 | 120 | CK_GPIO_ClockEnable(GPIOx); 121 | CK_GPIO_Init(GPIOx, sck_pin, CK_GPIO_AF, AFx, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 122 | CK_GPIO_Init(GPIOx, miso_pin, CK_GPIO_AF, AFx, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 123 | CK_GPIO_Init(GPIOx, mosi_pin, CK_GPIO_AF, AFx, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 124 | 125 | /* 126 | * Default: full duplex, (cpha=0,cpol=0),8bit data,No CRC,MSB First 127 | */ 128 | if(SPIx == SPI2){ 129 | SPIx->CR1 |= CK_SPIx_CR1_MSTR | CK_SPIx_CR1_SSM | CK_SPIx_CR1_SSI | CK_SPIx_CR1_Fclk_Div128; 130 | SPIx->CR1 |= CK_SPIx_CR1_SPE; // SPI Enable 131 | 132 | } 133 | else if(SPIx == SPI3){ 134 | SPIx->CR1 |= CK_SPIx_CR1_MSTR | CK_SPIx_CR1_SSM | CK_SPIx_CR1_SSI | CK_SPIx_CR1_Fclk_Div2; 135 | SPIx->CR1 |= CK_SPIx_CR1_SPE; // SPI Enable 136 | } 137 | else{ 138 | SPIx->CR1 |= CK_SPIx_CR1_MSTR | CK_SPIx_CR1_SSM | CK_SPIx_CR1_SSI | CK_SPIx_CR1_Fclk_Div4; 139 | SPIx->CR1 |= CK_SPIx_CR1_SPE; // SPI Enable 140 | } 141 | 142 | 143 | 144 | } 145 | 146 | void CK_SPI_Enable(SPI_TypeDef* spi_n){ 147 | 148 | spi_n->CR1 |= CK_SPIx_CR1_SPE;//SPI Enable 149 | 150 | } 151 | void CK_SPI_Disable(SPI_TypeDef* spi_n){ 152 | 153 | spi_n->CR1 &= ~CK_SPIx_CR1_SPE;//SPI Disable 154 | 155 | } 156 | 157 | void CK_SPI_EnableDMA(SPI_TypeDef* spi_n){ 158 | 159 | spi_n ->CR2 |= CK_SPIx_CR2_TXDMAEN;// | CK_SPIx_CR2_RXDMAEN; 160 | 161 | } 162 | 163 | void CK_SPI_DisableDMA(SPI_TypeDef* spi_n){ 164 | 165 | spi_n ->CR2 &= ~(CK_SPIx_CR2_TXDMAEN);// | CK_SPIx_CR2_RXDMAEN); 166 | 167 | } 168 | 169 | void CK_SPI_ChangeClock(SPI_TypeDef* spi_n, CK_SPIx_CR1_Fclk_Div clk){ 170 | 171 | spi_n->CR1 &= ~(7u<<3); 172 | spi_n->CR1 |= clk; 173 | 174 | } 175 | 176 | uint8_t CK_SPI_WriteRegister(uint8_t reg, uint8_t data, SPI_TypeDef* SPIn, GPIO_TypeDef* GPIOx_CS, uint16_t cs_pin){ 177 | uint8_t val = 0; 178 | CK_GPIO_ClearPin(GPIOx_CS, cs_pin); 179 | 180 | CK_SPI_Transfer(SPIn, reg); 181 | val = CK_SPI_Transfer(SPIn, data); 182 | 183 | CK_GPIO_SetPin(GPIOx_CS, cs_pin); 184 | return val; 185 | } 186 | 187 | void CK_SPI_ReadRegisterMulti(uint8_t reg, SPI_TypeDef* SPIn, GPIO_TypeDef* GPIOx_CS, uint16_t cs_pin, uint8_t* dataIn, int count){ 188 | 189 | CK_GPIO_ClearPin(GPIOx_CS, cs_pin); 190 | 191 | CK_SPI_Transfer(SPIn, reg); 192 | 193 | while (count--) { 194 | 195 | *dataIn++ = CK_SPI_Transfer(SPIn, 0); 196 | } 197 | 198 | CK_GPIO_SetPin(GPIOx_CS, cs_pin); 199 | 200 | } 201 | 202 | uint8_t CK_SPI_Transfer(SPI_TypeDef* SPIn, uint8_t data){ 203 | 204 | spi_variables.timeout = SPI_TIMEOUT; 205 | while(((SPIn)->SR & (CK_SPIx_SR_TXE | CK_SPIx_SR_RXNE)) == 0 || ((SPIn)->SR & CK_SPIx_SR_BSY)){ 206 | 207 | if(--spi_variables.timeout == 0x00){ 208 | CK_SPI_TimeOutCounter(SPIn); 209 | return 1; 210 | } 211 | } 212 | 213 | SPIn->DR = data; 214 | 215 | spi_variables.timeout = SPI_TIMEOUT; 216 | while(((SPIn)->SR & (CK_SPIx_SR_TXE | CK_SPIx_SR_RXNE)) == 0 || ((SPIn)->SR & CK_SPIx_SR_BSY)){ 217 | 218 | if(--spi_variables.timeout == 0x00){ 219 | CK_SPI_TimeOutCounter(SPIn); 220 | return 1; 221 | } 222 | } 223 | return SPIn->DR; 224 | } 225 | 226 | uint8_t CK_SPI_WaitTransfer(SPI_TypeDef* SPIn){ 227 | 228 | spi_variables.timeout = SPI_TIMEOUT; 229 | while(((SPIn)->SR & (CK_SPIx_SR_TXE | CK_SPIx_SR_RXNE)) == 0 || ((SPIn)->SR & CK_SPIx_SR_BSY)){ 230 | if(--spi_variables.timeout == 0x00){ 231 | CK_SPI_TimeOutCounter(SPIn); 232 | return 1; 233 | } 234 | } 235 | 236 | return 0; 237 | } 238 | 239 | int CK_SPI_CheckInitialized(SPI_TypeDef* SPIn){ 240 | 241 | int res; 242 | if(SPIn == SPI1){ 243 | res = spi_variables.spi1_init; 244 | } 245 | else if(SPIn == SPI2){ 246 | res = spi_variables.spi2_init; 247 | } 248 | else if(SPIn == SPI3){ 249 | res = spi_variables.spi3_init; 250 | } 251 | else{ 252 | res = 2; // Error 253 | } 254 | 255 | return res; 256 | 257 | } 258 | 259 | void CK_SPI_TimeOutCounter(SPI_TypeDef* spi){ 260 | if(spi == SPI1){ 261 | spi_variables.spi1_timeout++; 262 | } 263 | else if(spi == SPI2){ 264 | spi_variables.spi2_timeout++; 265 | } 266 | else if(spi == SPI3){ 267 | spi_variables.spi3_timeout++; 268 | } 269 | } 270 | 271 | uint32_t CK_SPI_GetTimeOut(SPI_TypeDef* spi){ 272 | 273 | uint32_t res; 274 | 275 | if(spi == SPI1){ 276 | res = spi_variables.spi1_timeout; 277 | } 278 | else if(spi == SPI2){ 279 | res = spi_variables.spi2_timeout; 280 | } 281 | else if(spi == SPI3){ 282 | res = spi_variables.spi3_timeout; 283 | } 284 | 285 | return res; 286 | } 287 | 288 | void CK_SPI_ResetTimeOut(SPI_TypeDef* spi){ 289 | 290 | if(spi == SPI1){ 291 | spi_variables.spi1_timeout = 0; 292 | } 293 | else if(spi == SPI2){ 294 | spi_variables.spi2_timeout = 0; 295 | } 296 | else if(spi == SPI3){ 297 | spi_variables.spi3_timeout = 0; 298 | } 299 | 300 | } 301 | -------------------------------------------------------------------------------- /Radar_Python/Radar_Record.py: -------------------------------------------------------------------------------- 1 | # pip3 install pyserial 2 | 3 | import serial.tools.list_ports 4 | import numpy as np 5 | import time 6 | import os 7 | import binascii 8 | 9 | ''' 10 | 11 | This code records radar data stream to a text file. 12 | ADC resolution is 12 bits, so 16 is required for each sample. 13 | Radar data format is: 512 (16bit) data = 1024 bytes each time. 14 | 15 | ''' 16 | 17 | # Best setting: 1.03e-3, 1200e-6, 5.85e9, 100e6, 500000, 500, 1, 0, 1 18 | RECORD_TIME = 10 # in sec 19 | SWEEP_TIME = 1.05e-3 # in sec 20 | SWEEP_GAP = 1000.0e-6 # in sec max 1500 21 | SWEEP_START = 5.8e9 22 | SWEEP_BW = 200e6 23 | SWEEP_TYPE = 0 # 0 for Sawtooth, 1 for Triangular 24 | SAMPLING_FREQUENCY = 250000 25 | NUMBER_OF_SAMPLES = 250 # NUMBER_OF_SAMPLES(16bit) = SAMPLING_FREQUENCY * SWEEP_TIME(int), max 2000 26 | TX_MODE = 1 # 0 for continuous tx, 1 for on off with tx 27 | TX_POWER_DBM = 0 28 | GAIN = 1 # Last gain stage (1 to 47) gain = -(4.7K / (100 + MCP4022)) MCP4022 max value is 5.1K for 63 decimal 29 | 30 | i_freq = 1e3 31 | hz_per_m = 0 32 | if SWEEP_BW: 33 | hz_per_m = int(1000 * ((3e8 * SWEEP_TIME * i_freq) / (2 * SWEEP_BW))) 34 | 35 | SWEEP_FREQ = 1 / (SWEEP_TIME + SWEEP_GAP) 36 | RECORD_COUNTER = int(RECORD_TIME * SWEEP_FREQ) 37 | 38 | def Serial_Init(): 39 | 40 | isPortConnected = False 41 | deviceId = '' 42 | 43 | # Find STM32 USB Device Id 44 | while not isPortConnected: 45 | ports = serial.tools.list_ports.comports() 46 | 47 | for device_ in ports: 48 | 49 | stm_string = device_.device 50 | 51 | for i in range(len(stm_string) - 8): 52 | 53 | str_to_look = "usbmodem" 54 | 55 | if stm_string[i: i + 8] == str_to_look: 56 | 57 | device_id_number = stm_string[i + 8: len(stm_string)] 58 | deviceId = "/dev/cu." + str_to_look + device_id_number 59 | print(device_) 60 | isPortConnected = True 61 | 62 | break 63 | 64 | ser = serial.Serial( 65 | port=deviceId, 66 | baudrate=115200, 67 | parity=serial.PARITY_NONE, 68 | stopbits=serial.STOPBITS_TWO, 69 | bytesize=serial.EIGHTBITS, 70 | #timeout=0.01 # can be None 71 | timeout=None 72 | ) 73 | 74 | # Clear all input data 75 | ser.flushInput() 76 | 77 | return ser 78 | 79 | 80 | def Configuration_Process(): 81 | 82 | isDone = False 83 | state = 0 84 | 85 | while not isDone: 86 | 87 | # Send start condition and hardware configuration paramaters 88 | if state == 0: 89 | 90 | ser.write("==".encode('ascii')) 91 | 92 | sw_t = np.uint16(SWEEP_TIME * 1e6) 93 | sw_t_msb = np.uint8((sw_t >> 8) & 0xFF) 94 | sw_t_lsb = np.uint8(sw_t & 0xFF) 95 | 96 | ser.write(binascii.hexlify(sw_t_msb)) 97 | ser.write(binascii.hexlify(sw_t_lsb)) 98 | 99 | sw_g = np.uint16(SWEEP_GAP * 1e6) 100 | sw_g_msb = np.uint8((sw_g >> 8) & 0xFF) 101 | sw_g_lsb = np.uint8(sw_g & 0xFF) 102 | 103 | ser.write(binascii.hexlify(sw_g_msb)) 104 | ser.write(binascii.hexlify(sw_g_lsb)) 105 | 106 | rec_t = np.uint8(RECORD_TIME) 107 | ser.write(binascii.hexlify(rec_t)) 108 | 109 | fs = np.uint16(SAMPLING_FREQUENCY / 1e3) 110 | fs_msb = np.uint8((fs >> 8) & 0xFF) 111 | fs_lsb = np.uint8(fs & 0xFF) 112 | 113 | ser.write(binascii.hexlify(fs_msb)) 114 | ser.write(binascii.hexlify(fs_lsb)) 115 | 116 | num_sample = np.uint16(NUMBER_OF_SAMPLES) 117 | num_sample_msb = np.uint8((num_sample >> 8) & 0xFF) 118 | num_sample_lsb = np.uint8(num_sample & 0xFF) 119 | 120 | ser.write(binascii.hexlify(num_sample_msb)) 121 | ser.write(binascii.hexlify(num_sample_lsb)) 122 | 123 | sweep_start = np.uint16(SWEEP_START / 1e7) 124 | sweep_start_msb = np.uint8((sweep_start >> 8) & 0xFF) 125 | sweep_start_lsb = np.uint8(sweep_start & 0xFF) 126 | 127 | ser.write(binascii.hexlify(sweep_start_msb)) 128 | ser.write(binascii.hexlify(sweep_start_lsb)) 129 | 130 | sweep_bw = np.uint16(SWEEP_BW / 1e6) 131 | sweep_bw_msb = np.uint8((sweep_bw >> 8) & 0xFF) 132 | sweep_bw_lsb = np.uint8(sweep_bw & 0xFF) 133 | 134 | ser.write(binascii.hexlify(sweep_bw_msb)) 135 | ser.write(binascii.hexlify(sweep_bw_lsb)) 136 | 137 | tx_mode = np.uint8(TX_MODE) 138 | ser.write(binascii.hexlify(tx_mode)) 139 | 140 | n = (((4700 / GAIN) - 100) * 64) / 5100 141 | gain_resistance_decimal = np.uint8(n) 142 | ser.write(binascii.hexlify(gain_resistance_decimal)) 143 | 144 | sw_type = np.uint8(SWEEP_TYPE) 145 | ser.write(binascii.hexlify(sw_type)) 146 | 147 | state = 1 148 | pass 149 | 150 | # Receive response and tx power from radar 151 | elif state == 1: 152 | 153 | # Wait until response is received or timeout 154 | while ser.inWaiting() == 0 and state == 1: 155 | pass 156 | 157 | if ser.inWaiting() > 0: 158 | config_read = ser.read(ser.inWaiting()) 159 | 160 | if config_read[0:2] == str("==").encode('ascii'): 161 | 162 | dbm = config_read[2] 163 | isDone = True 164 | pass 165 | 166 | return dbm 167 | 168 | if os.path.exists("data_record.txt"): 169 | os.remove("data_record.txt") 170 | data_record_file = open("data_record.txt", "w") 171 | 172 | ser = Serial_Init() 173 | TX_POWER_DBM = Configuration_Process() 174 | 175 | rx_counter = 0 176 | isRecordDone = 0 177 | 178 | data_record_file.write(str(RECORD_COUNTER)) 179 | data_record_file.write("\r\n") 180 | data_record_file.write(str(RECORD_TIME)) 181 | data_record_file.write("\r\n") 182 | data_record_file.write(str(int(SWEEP_TIME * 1000000))) 183 | data_record_file.write("\r\n") 184 | data_record_file.write(str(int(SWEEP_GAP * 1000000))) 185 | data_record_file.write("\r\n") 186 | data_record_file.write(str(SAMPLING_FREQUENCY)) 187 | data_record_file.write("\r\n") 188 | data_record_file.write(str(NUMBER_OF_SAMPLES)) 189 | data_record_file.write("\r\n") 190 | data_record_file.write(str(TX_MODE)) 191 | data_record_file.write("\r\n") 192 | data_record_file.write(str(TX_POWER_DBM)) 193 | data_record_file.write("\r\n") 194 | data_record_file.write(str(hz_per_m)) 195 | data_record_file.write("\r\n") 196 | 197 | start_time = time.time() 198 | 199 | while not isRecordDone: 200 | 201 | read_size = ser.inWaiting() 202 | 203 | # Read if available 204 | #if read_size > 0: 205 | 206 | calculation_start = time.time() 207 | 208 | # if fix byte is read first and last transfers will be ignored 209 | rx_data = ser.read(NUMBER_OF_SAMPLES * 2) # 16 bit NUMBER_OF_SAMPLES = 8 bit 2*NUMBER_OF_SAMPLES 210 | rx_data_str = str(binascii.b2a_hex(rx_data)) # takes hex values and stores them as string working perfectly 211 | 212 | rx_data_length = len(rx_data_str) 213 | 214 | # b'.....' so remove these 3 bytes 215 | data_record_file.write(rx_data_str[2:len(rx_data_str) - 1]) 216 | data_record_file.write("\r\n") 217 | 218 | rx_counter += 1; 219 | if rx_counter == RECORD_COUNTER: 220 | isRecordDone = 1 221 | done_time = time.time() - start_time 222 | print("Completed in ", str(round(done_time, 1)), "second.") 223 | 224 | calculation_done = time.time() - calculation_start 225 | 226 | print("Calculation time: ", str(round(calculation_done, 4)), " rx counter: ", str(rx_counter)) 227 | #print(rx_counter) 228 | 229 | 230 | 231 | print("TX Power: ", str(TX_POWER_DBM)) 232 | print("Meters per KHz: ",str(hz_per_m)) 233 | exit(1) 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_CONFIGURATION.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_CONFIGURATION.h" 3 | 4 | #include "USBD_CDC/CK_USBD_INTERFACE.h" 5 | #include "CK_TIME_HAL.h" 6 | 7 | #include "CK_TQP5523.h" 8 | #include "CK_ADF4158.h" 9 | 10 | #define CHECK_FREQ 10 // 10Hz 11 | #define PYTHON_BUFFER_SIZE 64 12 | 13 | uint8_t isStarted = 0; 14 | 15 | uint8_t config_buffer[PYTHON_BUFFER_SIZE]; 16 | uint16_t config_index; 17 | 18 | uint32_t record_time_counter = 0; 19 | uint8_t record_time = 0; 20 | uint32_t sweep_time_config = 0; 21 | uint32_t sweep_gap_config = 0; 22 | uint32_t sampling_frequency = 0; 23 | uint32_t number_of_samples = 0; 24 | uint32_t sweep_start_freq = 0; 25 | uint32_t sweep_bw = 0; 26 | uint8_t tx_mode = 0; 27 | uint8_t gain_value = 0; 28 | uint8_t sweep_type = 0; 29 | 30 | typedef enum{ 31 | 32 | IDLE, 33 | SEND_TX_POWER, 34 | READ_RECORD_TIME 35 | 36 | }CONFIG_STATES_E; 37 | 38 | CONFIG_STATES_E config_state = IDLE; 39 | 40 | void CK_CONFIGURATION_Init(void){ 41 | 42 | for(int i = 0; i < PYTHON_BUFFER_SIZE; i++){ 43 | config_buffer[i] = 0; 44 | } 45 | 46 | config_index = 0; 47 | 48 | record_time_counter = 0; 49 | 50 | record_time = 0; 51 | 52 | sweep_time_config = 0; 53 | 54 | sweep_gap_config = 0; 55 | 56 | sampling_frequency = 0; 57 | 58 | number_of_samples = 0; 59 | 60 | sweep_start_freq = 0; 61 | 62 | sweep_bw = 0; 63 | 64 | isStarted = 0; 65 | 66 | tx_mode = 0; 67 | 68 | gain_value = 0; 69 | 70 | } 71 | 72 | void CK_CONFIGURATION_InitHardware(uint8_t mode){ 73 | 74 | CK_CONFIGURATION_Init(); 75 | 76 | uint8_t rx_data = 0; 77 | 78 | if(mode == 1){ 79 | // Python will send start charcters to Radar 80 | while(isStarted == 0){ 81 | 82 | // Read received data over usb 83 | while(CK_USBD_ReadData(&rx_data)){ 84 | // Firs 2 bytes are indicator sign decode rest of the numbers. 85 | if(config_index >= 2){ 86 | config_buffer[config_index++] = CK_CONFIGURATION_DecodeData(rx_data); 87 | } 88 | else{ 89 | config_buffer[config_index++] = rx_data; 90 | } 91 | 92 | CK_TIME_DelayMilliSec(1); 93 | } 94 | 95 | // HOST will start state machine according to the data received. 96 | if(config_buffer[0] == '=' && config_buffer[1] == '=' && config_state == IDLE){ 97 | 98 | uint8_t sw_t_msb = (config_buffer[2] << 4) | config_buffer[3]; 99 | uint8_t sw_t_lsb = (config_buffer[4] << 4) | config_buffer[5]; 100 | sweep_time_config = (sw_t_msb << 8) | (sw_t_lsb); 101 | 102 | uint8_t sw_g_msb = (config_buffer[6] << 4) | config_buffer[7]; 103 | uint8_t sw_g_lsb = (config_buffer[8] << 4) | config_buffer[9]; 104 | sweep_gap_config = (sw_g_msb << 8) | (sw_g_lsb); 105 | 106 | record_time = (config_buffer[10] << 4) | config_buffer[11]; 107 | uint32_t sweep_p_microsec = sweep_time_config + sweep_gap_config; 108 | record_time_counter = (record_time * 1000.0f) / ((float)sweep_p_microsec / 1000.0f); 109 | 110 | uint8_t fs_msb = (config_buffer[12] << 4) | config_buffer[13]; 111 | uint8_t fs_lsb = (config_buffer[14] << 4) | config_buffer[15]; 112 | sampling_frequency = (fs_msb << 8) | (fs_lsb); 113 | 114 | uint8_t num_sample_msb = (config_buffer[16] << 4) | config_buffer[17]; 115 | uint8_t num_sample_lsb = (config_buffer[18] << 4) | config_buffer[19]; 116 | number_of_samples = (num_sample_msb << 8) | (num_sample_lsb); 117 | 118 | uint8_t sweep_start_msb = (config_buffer[20] << 4) | config_buffer[21]; 119 | uint8_t sweep_start_lsb = (config_buffer[22] << 4) | config_buffer[23]; 120 | sweep_start_freq = (sweep_start_msb << 8) | (sweep_start_lsb); 121 | 122 | uint8_t sweep_bw_msb = (config_buffer[24] << 4) | config_buffer[25]; 123 | uint8_t sweep_bw_lsb = (config_buffer[26] << 4) | config_buffer[27]; 124 | sweep_bw = (sweep_bw_msb << 8) | (sweep_bw_lsb); 125 | 126 | tx_mode = (config_buffer[28] << 4) | config_buffer[29]; 127 | 128 | gain_value = (config_buffer[30] << 4) | config_buffer[31]; 129 | 130 | sweep_type = (config_buffer[32] << 4) | config_buffer[33]; 131 | 132 | config_index = 0; 133 | 134 | config_state = SEND_TX_POWER; 135 | 136 | } 137 | 138 | switch(config_state){ 139 | 140 | case IDLE: 141 | 142 | break; 143 | 144 | case SEND_TX_POWER: 145 | 146 | 147 | CK_USBD_WriteTxCircularBuffer('='); 148 | CK_USBD_WriteTxCircularBuffer('='); 149 | 150 | CK_TQP5523_Enable(); 151 | 152 | CK_TQP5523_CheckOutputPower(); 153 | int dbm_power = CK_TQP5523_ReadDetectorOutputDBM(); 154 | 155 | CK_TQP5523_Disable(); 156 | 157 | CK_USBD_WriteTxCircularBuffer(dbm_power); 158 | CK_USBD_Transmit(); 159 | 160 | config_state = READ_RECORD_TIME; 161 | 162 | break; 163 | 164 | case READ_RECORD_TIME: 165 | 166 | isStarted = 1; 167 | 168 | break; 169 | 170 | } 171 | } 172 | 173 | } 174 | else if(mode == 2){ 175 | 176 | sweep_time_config = 2030; 177 | 178 | sweep_gap_config = 700; 179 | 180 | record_time = 10; 181 | uint32_t sweep_p_microsec = sweep_time_config + sweep_gap_config; 182 | record_time_counter = (record_time * 1000.0f) / ((float)sweep_p_microsec / 1000.0f); 183 | 184 | sampling_frequency = 250; 185 | 186 | number_of_samples = 500; 187 | 188 | sweep_start_freq = 580; 189 | 190 | sweep_bw = 200; 191 | 192 | sweep_type = 0; // 0 for Sawtooth, 1 for Triangular 193 | 194 | tx_mode = 2; // 0 for continuous tx, 1 for on off with tx, 2 for off 195 | 196 | gain_value = 1; 197 | 198 | config_index = 0; 199 | 200 | } 201 | else if(mode == 3){ 202 | 203 | sweep_time_config = 1000; 204 | 205 | sweep_gap_config = 0; 206 | 207 | record_time = 20; 208 | uint32_t sweep_p_microsec = sweep_time_config + sweep_gap_config; 209 | record_time_counter = (record_time * 1000.0f) / ((float)sweep_p_microsec / 1000.0f); 210 | 211 | sampling_frequency = 250; 212 | 213 | number_of_samples = 250; 214 | 215 | sweep_start_freq = 570; //5.7GHz 216 | 217 | sweep_bw = 300; 218 | 219 | sweep_type = 1; // 0 for Sawtooth, 1 for Triangular 220 | 221 | tx_mode = 1; // 0 for continuous tx, 1 for on off with tx, 2 for off 222 | 223 | gain_value = 1; 224 | 225 | config_index = 0; 226 | 227 | } 228 | 229 | } 230 | 231 | uint32_t CK_CONFIGURATION_GetRecordTimeCounter(void){ 232 | 233 | return record_time_counter; 234 | 235 | } 236 | 237 | uint8_t CK_CONFIGURATION_GetRecordTime(void){ 238 | 239 | return record_time; 240 | 241 | } 242 | 243 | uint32_t CK_CONFIGURATION_GetSweepTime(void){ 244 | 245 | return sweep_time_config; 246 | 247 | } 248 | 249 | uint32_t CK_CONFIGURATION_GetSweepGap(void){ 250 | 251 | return sweep_gap_config; 252 | 253 | } 254 | 255 | uint32_t CK_CONFIGURATION_GetSamplingFrequency(void){ 256 | 257 | return sampling_frequency; 258 | 259 | } 260 | 261 | uint32_t CK_CONFIGURATION_GetSampleNumber(void){ 262 | 263 | return number_of_samples; 264 | 265 | } 266 | 267 | uint32_t CK_CONFIGURATION_GetSweepStartFrequency(void){ 268 | 269 | return sweep_start_freq; 270 | 271 | } 272 | 273 | uint32_t CK_CONFIGURATION_GetSweepBandwith(void){ 274 | 275 | return sweep_bw; 276 | 277 | } 278 | 279 | uint8_t CK_CONFIGURATION_GetTXMode(void){ 280 | 281 | return tx_mode; 282 | 283 | } 284 | 285 | uint8_t CK_CONFIGURATION_SweepType(void){ 286 | 287 | return sweep_type; 288 | 289 | } 290 | 291 | uint8_t CK_CONFIGURATION_GetGainValue(void){ 292 | 293 | return gain_value; 294 | 295 | } 296 | 297 | uint8_t CK_CONFIGURATION_DecodeData(uint8_t rx_data){ 298 | 299 | // Received data is ascii coded 0-9 -> 48-57, a-f -> 97-102 300 | // if data is 0x2a received data will be 50(2) and 97(a) 301 | uint8_t data_decoded = 0; 302 | if(rx_data >= 48 && rx_data <= 57){ 303 | data_decoded = rx_data - 48; 304 | } 305 | else if(rx_data >= 97 && rx_data <= 102){ 306 | if(rx_data == 97){ 307 | data_decoded = 0xa; 308 | } 309 | else if(rx_data == 98){ 310 | data_decoded = 0xb; 311 | } 312 | else if(rx_data == 99){ 313 | data_decoded = 0xc; 314 | } 315 | else if(rx_data == 100){ 316 | data_decoded = 0xd; 317 | } 318 | else if(rx_data == 101){ 319 | data_decoded = 0xe; 320 | } 321 | else if(rx_data == 102){ 322 | data_decoded = 0xf; 323 | } 324 | } 325 | 326 | return data_decoded; 327 | } 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_MAX1426.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_MAX1426.h" 3 | #include "CK_CONFIGURATION.h" 4 | 5 | #include "USBD_CDC/CK_USBD_INTERFACE.h" 6 | 7 | #include "CK_TIME_HAL.h" 8 | #include "CK_GPIO.h" 9 | 10 | #include "stm32f4xx.h" 11 | 12 | /* 13 | * 14 | * MAX1426 ADC PINS: 15 | * MAX1426 samples at falling edge of the ADC_CLK and the data is available 16 | * at the rising edge of the ADC_CLK. 17 | * 18 | * PC10 -> ADC_OE, Active Low Output enable pin, when enabled conversion starts 19 | * 20 | * PA9 -> ADC_CLK, TIM1_CH2 21 | * PA10 -> ADC_CLK_EXTIN, TIM1_CH3 and EXTI 22 | * 23 | * PB10 -> ADC_D0 24 | * PB11 -> ADC_D1 25 | * PB12 -> ADC_D2 26 | * PB13 -> ADC_D3 27 | * PB14 -> ADC_D4 28 | * PB15 -> ADC_D5 29 | * PC6 -> ADC_D6 30 | * PC7 -> ADC_D7 31 | * PC8 -> ADC_D8 32 | * PC9 -> ADC_D9 33 | * 34 | * 35 | */ 36 | #define MAX1426_EXTI_GPIO GPIOA 37 | #define MAX1426_EXTI_PIN 10 38 | 39 | #define MAX1426_CLK_GPIO GPIOA 40 | #define MAX1426_CLK_PIN 9 41 | 42 | #define MAX1426_D0_5_GPIO GPIOB 43 | #define MAX1426_D6_9_GPIO GPIOC 44 | 45 | #define MAX1426_OE_GPIO GPIOC 46 | #define MAX1426_OE_PIN 10 47 | 48 | #define MAX1426_D0 10 49 | #define MAX1426_D1 11 50 | #define MAX1426_D2 12 51 | #define MAX1426_D3 13 52 | #define MAX1426_D4 14 53 | #define MAX1426_D5 15 54 | #define MAX1426_D6 6 55 | #define MAX1426_D7 7 56 | #define MAX1426_D8 8 57 | #define MAX1426_D9 9 58 | 59 | 60 | #define DEBUG_TIMING 0 61 | 62 | #define TEST_MODE 0 63 | 64 | uint32_t MAX1426_BUFFER_SIZE = 0; 65 | 66 | uint16_t adc_data_10bit = 0; 67 | uint16_t adc_data_counter = 0; 68 | 69 | uint8_t gpiob_read = 0; 70 | uint8_t gpioc_read = 0; 71 | 72 | TIM_HandleTypeDef htim1; 73 | 74 | uint16_t test_counter = 0; 75 | 76 | uint8_t recordDone = 0; 77 | 78 | uint16_t max1426_buffer[4096]; 79 | uint32_t max1426_buffer_counter = 0; 80 | 81 | 82 | void CK_MAX1426_Init(void){ 83 | 84 | // MAX1426 Implementation. 85 | 86 | // External interrupt in for triggering rising edge of the adc clock 87 | // MAX1426 samples the data at the falling edge of the clock 88 | // new data is available at the rising edge of the clock 89 | 90 | // Init external interrupt pin for adc clock rising edge triggering 91 | 92 | // GPIO Clock is enabled in the main 93 | 94 | MAX1426_BUFFER_SIZE = CK_CONFIGURATION_GetSampleNumber(); 95 | 96 | CK_GPIO_Init(MAX1426_EXTI_GPIO, MAX1426_EXTI_PIN, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_PULLDOWN); 97 | 98 | CK_GPIO_Init(MAX1426_CLK_GPIO, MAX1426_CLK_PIN, CK_GPIO_AF, CK_GPIO_AF1, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 99 | 100 | CK_GPIO_Init(MAX1426_OE_GPIO, MAX1426_OE_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_HIGH, CK_GPIO_NOPUPD); 101 | CK_MAX1426_ADC_OutputDisable(); 102 | 103 | // MAX1426 Data Input 104 | CK_GPIO_Init(MAX1426_D0_5_GPIO, MAX1426_D0, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 105 | CK_GPIO_Init(MAX1426_D0_5_GPIO, MAX1426_D1, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 106 | CK_GPIO_Init(MAX1426_D0_5_GPIO, MAX1426_D2, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 107 | CK_GPIO_Init(MAX1426_D0_5_GPIO, MAX1426_D3, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 108 | CK_GPIO_Init(MAX1426_D0_5_GPIO, MAX1426_D4, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 109 | CK_GPIO_Init(MAX1426_D0_5_GPIO, MAX1426_D5, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 110 | CK_GPIO_Init(MAX1426_D6_9_GPIO, MAX1426_D6, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 111 | CK_GPIO_Init(MAX1426_D6_9_GPIO, MAX1426_D7, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 112 | CK_GPIO_Init(MAX1426_D6_9_GPIO, MAX1426_D8, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 113 | CK_GPIO_Init(MAX1426_D6_9_GPIO, MAX1426_D9, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 114 | 115 | CK_MAX1426_EXTI_Init(); 116 | 117 | CK_MAX1426_PWM_Init(); 118 | 119 | } 120 | 121 | void CK_MAX1426_EXTI_Init(void){ 122 | 123 | RCC->APB2ENR |= 1u << 14; // SYSCFG Clock Enable 124 | 125 | // 0u for GPIOA, 1u for GPIOB, 2u for GPIOC 126 | SYSCFG->EXTICR[2] |= (0u << 8); // External interrupt 10 is set to GPIOA Pin10 127 | 128 | EXTI->IMR |= (1u << 10); // Line 10 Interrupt Mask Request 129 | 130 | EXTI->EMR |= (1u << 10); // Line 10 Event Mask Request 131 | 132 | EXTI->RTSR |= (1u << 10); // Rising edge detection for each line 133 | 134 | //EXTI->FTSR |= (1u << 10); // Falling edge detection for each line 135 | 136 | NVIC_SetPriority(EXTI15_10_IRQn, 0); 137 | 138 | NVIC_EnableIRQ(EXTI15_10_IRQn); 139 | 140 | } 141 | 142 | void CK_MAX1426_PWM_Init(void){ 143 | 144 | __HAL_RCC_TIM1_CLK_ENABLE(); 145 | 146 | // TIMER1 CH2 Configuration 147 | htim1.Instance = TIM1; 148 | htim1.Init.Prescaler = 0; // Divide 168MHz to 0+1 = 168MHz timer clock 149 | htim1.Init.CounterMode = TIM_COUNTERMODE_UP; 150 | uint32_t pwm_freq = CK_CONFIGURATION_GetSamplingFrequency() * 1000; 151 | if(pwm_freq >= 500000){ 152 | pwm_freq = 500000; 153 | } 154 | htim1.Init.Period = 168000000 / pwm_freq; 155 | htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2; 156 | htim1.Init.RepetitionCounter = 0; 157 | htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; 158 | if (HAL_TIM_PWM_Init(&htim1) != HAL_OK); 159 | 160 | TIM_OC_InitTypeDef sConfigOC = {0}; 161 | sConfigOC.OCMode = TIM_OCMODE_PWM1; 162 | sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; 163 | sConfigOC.OCNPolarity = TIM_OCPOLARITY_HIGH; 164 | sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; 165 | sConfigOC.OCIdleState = TIM_OCIDLESTATE_SET; 166 | sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; 167 | 168 | sConfigOC.Pulse = htim1.Init.Period / 2; // 50% Duty_cycle 169 | if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK); 170 | 171 | } 172 | 173 | void CK_MAX1426_PWM_Start(void){ 174 | 175 | HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); 176 | 177 | } 178 | 179 | void CK_MAX1426_PWM_Stop(void){ 180 | HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2); 181 | } 182 | 183 | void CK_MAX1426_ADC_OutputDisable(void){ 184 | CK_GPIO_SetPin(MAX1426_OE_GPIO, MAX1426_OE_PIN); 185 | } 186 | 187 | void CK_MAX1426_ADC_OutputEnable(void){ 188 | CK_GPIO_ClearPin(MAX1426_OE_GPIO, MAX1426_OE_PIN); 189 | } 190 | 191 | uint16_t CK_MAX1426_Get_ADCResult(void){ 192 | return adc_data_10bit; 193 | } 194 | 195 | uint16_t CK_MAX1426_Get_Counter(void){ 196 | return max1426_buffer_counter; 197 | } 198 | 199 | void CK_MAX1426_Reset_Counter(void){ 200 | max1426_buffer_counter = 0; 201 | } 202 | 203 | uint8_t CK_MAX1426_IsRecordDone(void){ 204 | return recordDone; 205 | } 206 | 207 | void CK_MAX1426_ResetRecordDone(void){ 208 | recordDone = 0; 209 | } 210 | 211 | void CK_MAX1426_TransferSamples(void){ 212 | 213 | #if DEBUG_TIMING_ 214 | uint32_t adc_tx_t1 = CK_TIME_GetMicroSec(); 215 | #endif 216 | 217 | uint16_t current_data = 0; 218 | uint8_t adc_lsb = 0; 219 | uint8_t adc_msb = 0; 220 | 221 | for(int i = 0; i < MAX1426_BUFFER_SIZE; i++){ 222 | 223 | current_data = max1426_buffer[i]; 224 | 225 | #if TEST_MODE 226 | static uint32_t counter = 0; 227 | current_data = (uint16_t)counter++; 228 | if(counter == 65536) counter = 0; 229 | #endif 230 | 231 | adc_msb = (uint8_t)((current_data >> 8) & 0xFF); 232 | adc_lsb = (uint8_t)(current_data & 0xFF); 233 | 234 | CK_USBD_WriteTxCircularBuffer(adc_msb); 235 | CK_USBD_WriteTxCircularBuffer(adc_lsb); 236 | 237 | } 238 | 239 | #if DEBUG_TIMING_ 240 | uint32_t adc_tx_t2 = CK_TIME_GetMicroSec() - adc_tx_t1; 241 | adc_tx_t2++; 242 | 243 | uint32_t adc_tx_t3 = CK_TIME_GetMicroSec(); 244 | 245 | CK_USBD_Transmit(); 246 | 247 | uint32_t adc_tx_t4 = CK_TIME_GetMicroSec() - adc_tx_t3; 248 | UNUSED(adc_tx_t4); 249 | #else 250 | 251 | CK_USBD_Transmit(); 252 | 253 | #endif 254 | 255 | 256 | } 257 | 258 | void EXTI15_10_IRQHandler(void){ 259 | 260 | // It will come here at the rising edge of the ADC_CLK 261 | // Read data from D0-D9 pins at once as quick as possible. 262 | 263 | // This part is taking 1-2 microseconds so 250KHz sample would be fine. 264 | 265 | #if DEBUG_TIMING 266 | uint32_t time1 = CK_TIME_GetMicroSec(); 267 | #endif 268 | 269 | gpiob_read = (uint8_t)((GPIOB->IDR >> 10) & 0x3F); 270 | gpioc_read = (uint8_t)((GPIOC->IDR >> 6) & 0x0F); 271 | 272 | adc_data_10bit = (((gpioc_read << 6) | gpiob_read) & 0x03FF); 273 | 274 | max1426_buffer[max1426_buffer_counter++] = adc_data_10bit; 275 | 276 | if(max1426_buffer_counter == MAX1426_BUFFER_SIZE){ 277 | 278 | recordDone = 1; 279 | } 280 | 281 | #if DEBUG_TIMING 282 | uint32_t t_buffer[MAX1426_BUFFER_SIZE]; 283 | UNUSED(t_buffer); 284 | static uint32_t t_buffer_counter = 0; 285 | 286 | uint32_t time2 = CK_TIME_GetMicroSec() - time1; 287 | 288 | t_buffer[t_buffer_counter++] = time2; 289 | if(t_buffer_counter == MAX1426_BUFFER_SIZE){ 290 | t_buffer_counter = 0; 291 | } 292 | 293 | 294 | #endif 295 | 296 | EXTI->PR |= 1u << 10; // Clear interrupt 297 | 298 | } 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/CK_USBD_INTERFACE.c: -------------------------------------------------------------------------------- 1 | 2 | #include "USBD_CDC/usbd_core.h" 3 | #include "USBD_CDC/usbd_desc.h" 4 | #include "USBD_CDC/usbd_cdc.h" 5 | #include "USBD_CDC/usbd_cdc_if.h" 6 | 7 | #include "USBD_CDC/CK_USBD_BUFFER.h" 8 | #include "USBD_CDC/CK_USBD_INTERFACE.h" 9 | 10 | #define USB_BUFFER_SIZE 4096 11 | /* 12 | * In this mode the transfer data is written to transfer buffer directly 13 | * Write more than BUFFER_SIZE will be ignored. 14 | * In this way memcpy time is not needed. Data is ready to transfer without second operation. 15 | */ 16 | #define FAST_TRANSFER 1 17 | #define DUAL_BUFFERING 0 18 | 19 | USBD_HandleTypeDef hUsbDeviceFS; // USB Device Core handle declaration 20 | 21 | circularBuffer_t usbd_transfer_cb; 22 | 23 | circularBuffer_t usbd_receive_cb; 24 | 25 | uint8_t copy_buffer[USB_BUFFER_SIZE]; 26 | uint8_t copy_buffer2[USB_BUFFER_SIZE]; 27 | 28 | uint32_t copy_length = 0; 29 | uint32_t copy_length2 = 0; 30 | uint8_t which_buffer = 0; 31 | 32 | void CK_USBD_Init(void){ 33 | 34 | // Init Device Library, add supported class and start the library 35 | if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK){ 36 | //Error_Handler(); 37 | } 38 | if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK){ 39 | //Error_Handler(); 40 | } 41 | if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK){ 42 | //Error_Handler(); 43 | } 44 | if (USBD_Start(&hUsbDeviceFS) != USBD_OK){ 45 | //Error_Handler(); 46 | } 47 | 48 | CK_USBD_BUFFER_Init(&usbd_transfer_cb, USB_BUFFER_SIZE); 49 | 50 | CK_USBD_BUFFER_Init(&usbd_receive_cb, USB_BUFFER_SIZE); 51 | 52 | } 53 | 54 | void CK_USBD_Start(void){ 55 | 56 | USBD_Start(&hUsbDeviceFS); 57 | } 58 | 59 | void CK_USBD_Stop(void){ 60 | USBD_Stop(&hUsbDeviceFS); 61 | } 62 | 63 | int CK_USBD_Transmit(void){ 64 | 65 | #if FAST_TRANSFER && DUAL_BUFFERING 66 | 67 | if(which_buffer == 0){ 68 | 69 | which_buffer = 1; 70 | 71 | if(CDC_Transmit_FS(copy_buffer, copy_length) == USBD_OK){ 72 | copy_length = 0; 73 | return 1; // OK 74 | } 75 | } 76 | else if(which_buffer == 1){ 77 | 78 | which_buffer = 0; 79 | 80 | if(CDC_Transmit_FS(copy_buffer2, copy_length2) == USBD_OK){ 81 | copy_length2 = 0; 82 | return 1; // OK 83 | } 84 | } 85 | 86 | #elif FAST_TRANSFER 87 | 88 | if(CDC_Transmit_FS(copy_buffer, copy_length) == USBD_OK){ 89 | copy_length = 0; 90 | return 1; // OK 91 | } 92 | 93 | #else 94 | 95 | CK_USBD_BUFFER_GetBuffer(&usbd_transfer_cb, copy_buffer, ©_length); 96 | 97 | if(copy_length != 0){ 98 | if(CDC_Transmit_FS(copy_buffer, copy_length) == USBD_OK){ 99 | 100 | return 1; // OK 101 | } 102 | } 103 | 104 | #endif 105 | return 0; 106 | 107 | } 108 | 109 | int CK_USBD_ReadData(uint8_t* data){ 110 | 111 | if(!CK_USBD_BUFFER_IsBufferEmpty(&usbd_receive_cb)){ 112 | CK_USBD_BUFFER_BufferRead(&usbd_receive_cb, data); 113 | return 1; 114 | } 115 | 116 | return 0; // Data is not available 117 | } 118 | 119 | int CK_USBD_WriteRxCircularBuffer(uint8_t* Buf, uint32_t* Len){ 120 | 121 | // Later add FAST_TRANSFER mode for reception as well where 122 | // array should be copied to circular buffer directly once. 123 | 124 | uint32_t receivedLength = *Len; // point to the received length address which is the length number. 125 | 126 | for(int i = 0; i < receivedLength; i++){ 127 | if(!CK_USBD_BUFFER_IsBufferFull(&usbd_receive_cb)){ 128 | uint8_t data = Buf[i]; 129 | CK_USBD_BUFFER_BufferWrite(&usbd_receive_cb, data); 130 | } 131 | else{ 132 | return 0; // Full, could not write 133 | } 134 | } 135 | 136 | return 1; // OK 137 | } 138 | 139 | int CK_USBD_WriteTxCircularBuffer(uint8_t data){ 140 | 141 | #if FAST_TRANSFER && DUAL_BUFFERING 142 | 143 | if(which_buffer == 0){ 144 | if(copy_length < USB_BUFFER_SIZE){ 145 | copy_buffer[copy_length++] = data; 146 | return 1; // OK 147 | } 148 | } 149 | else if(which_buffer == 1){ 150 | if(copy_length2 < USB_BUFFER_SIZE){ 151 | copy_buffer2[copy_length2++] = data; 152 | return 1; // OK 153 | } 154 | } 155 | #elif FAST_TRANSFER 156 | 157 | if(copy_length <= USB_BUFFER_SIZE){ 158 | copy_buffer[copy_length++] = data; 159 | return 1; // OK 160 | } 161 | 162 | #else 163 | 164 | if(!CK_USBD_BUFFER_IsBufferFull(&usbd_transfer_cb)){ 165 | CK_USBD_BUFFER_BufferWrite(&usbd_transfer_cb, data); 166 | return 1; // OK 167 | } 168 | 169 | #endif 170 | 171 | return 0; // Full, could not write 172 | 173 | } 174 | 175 | void CK_USBD_ClearBufferIndex(void){ 176 | 177 | copy_length = 0; 178 | copy_length2 = 0; 179 | 180 | } 181 | 182 | void CK_USBD_IntPrint(int32_t num){ 183 | if(num < 0){ 184 | CK_USBD_WriteTxCircularBuffer((uint8_t)'-'); 185 | num *= -1; 186 | } 187 | int32_t tmp[10]; 188 | int numOfDigits = 0; 189 | int limit = 10; 190 | 191 | for(int i=0; i < limit; i++){ 192 | if(num >= 10){ 193 | tmp[i] = (int32_t)num % 10; 194 | num = num - tmp[i]; 195 | num = num / 10; 196 | } 197 | else{ 198 | tmp[i] = num; 199 | numOfDigits = i; 200 | i = limit; 201 | } 202 | } 203 | for(int i = numOfDigits; i >= 0; i--){ 204 | CK_USBD_WriteTxCircularBuffer((uint8_t)tmp[i] + 48); //for ASCII code of number 205 | } 206 | } 207 | 208 | void CK_USBD_IntPrintln(int32_t num){ 209 | if(num < 0){ 210 | CK_USBD_WriteTxCircularBuffer((uint8_t)'-'); 211 | num *= -1; 212 | } 213 | int32_t tmp[10]; 214 | int numOfDigits = 0; 215 | int limit = 10; 216 | 217 | for(int i = 0; i < limit; i++){ 218 | if(num >= 10){ 219 | tmp[i] = (int32_t)num % 10; 220 | num = num - tmp[i]; 221 | num = num / 10; 222 | } 223 | else{ 224 | tmp[i] = num; 225 | numOfDigits = i; 226 | i = limit; 227 | } 228 | } 229 | for(int i=numOfDigits; i >= 0; i--){ 230 | CK_USBD_WriteTxCircularBuffer((uint8_t)tmp[i] + 48); //for ASCII code of number 231 | } 232 | CK_USBD_WriteTxCircularBuffer((uint8_t)10); //for ASCII new line 233 | 234 | } 235 | 236 | void CK_USBD_FloatPrintln(float num){ 237 | int flag = 0; 238 | num = num * 100; // 2 digit after comma 239 | int intnum = (int)num; 240 | const int limit = 10; // 10 digit number max 241 | if(intnum < 0){ 242 | CK_USBD_WriteTxCircularBuffer((uint8_t)'-'); 243 | intnum *= -1; 244 | } 245 | if(intnum < 10){ // 0.00 246 | flag = 1; 247 | } 248 | else if(intnum >= 10 && intnum <= 99){ // 0.01 to 0.99 249 | flag = 2; 250 | } 251 | 252 | int tmp[limit]; 253 | int numOfDigits = 0; 254 | for(int i = 0; i < limit; i++){ 255 | if(intnum>=10){ 256 | tmp[i] = (int)intnum % 10; 257 | intnum = intnum - tmp[i]; 258 | intnum = intnum / 10; 259 | } 260 | else{ 261 | tmp[i] = intnum; 262 | numOfDigits = i; // get num of digits 263 | i = limit; // end loop 264 | } 265 | } 266 | if(flag==1){ // make 0.00 267 | tmp[1] = 0;tmp[2] = 0; 268 | numOfDigits = 2; 269 | } 270 | if(flag==2){ // add 0 for 0.01 to 0.99 numbers 271 | tmp[++numOfDigits] = 0; 272 | } 273 | 274 | for(int i=numOfDigits; i >= 0; i--){ 275 | if(i>1){ 276 | CK_USBD_WriteTxCircularBuffer((uint8_t)tmp[i] + 48); //for ASCII code of number 277 | } 278 | else if(i==1){ 279 | CK_USBD_WriteTxCircularBuffer((uint8_t)46); //for ASCII '.' 280 | CK_USBD_WriteTxCircularBuffer((uint8_t)tmp[i] + 48); //for ASCII code of number 281 | } 282 | else{ 283 | CK_USBD_WriteTxCircularBuffer((uint8_t)tmp[i] + 48); //for ASCII code of number 284 | } 285 | } 286 | CK_USBD_WriteTxCircularBuffer((uint8_t)10); //for ASCII new line 287 | 288 | } 289 | 290 | void CK_USBD_FloatPrint(float num){ 291 | int flag = 0; 292 | num = num * 100; // 2 digit after comma 293 | int intnum = (int)num; 294 | const int limit = 10; // 10 digit number max 295 | if(intnum < 0){ 296 | CK_USBD_WriteTxCircularBuffer((uint8_t)'-'); 297 | intnum *= -1; 298 | } 299 | if(intnum < 10){ // 0.00 300 | flag = 1; 301 | } 302 | else if(intnum >= 10 && intnum <= 99){ // 0.01 to 0.99 303 | flag = 2; 304 | } 305 | 306 | int tmp[limit]; 307 | int numOfDigits = 0; 308 | for(int i = 0; i < limit; i++){ 309 | if(intnum >= 10){ 310 | tmp[i] = (int)intnum % 10; 311 | intnum = intnum - tmp[i]; 312 | intnum = intnum / 10; 313 | } 314 | else{ 315 | tmp[i] = intnum; 316 | numOfDigits = i; // get num of digits 317 | i = limit; // end loop 318 | } 319 | } 320 | if(flag == 1){ // make 0.00 321 | tmp[1] = 0;tmp[2] = 0; 322 | numOfDigits = 2; 323 | } 324 | if(flag == 2){ // add 0 for 0.01 to 0.99 numbers 325 | tmp[++numOfDigits] = 0; 326 | } 327 | 328 | for(int i = numOfDigits; i >= 0; i--){ 329 | if(i > 1){ 330 | CK_USBD_WriteTxCircularBuffer((uint8_t)tmp[i] + 48); //for ASCII code of number 331 | } 332 | else if(i == 1){ 333 | CK_USBD_WriteTxCircularBuffer((uint8_t)46); //for ASCII '.' 334 | CK_USBD_WriteTxCircularBuffer((uint8_t)tmp[i] + 48); //for ASCII code of number 335 | } 336 | else{ 337 | CK_USBD_WriteTxCircularBuffer((uint8_t)tmp[i] + 48); //for ASCII code of number 338 | } 339 | } 340 | 341 | } 342 | 343 | void CK_USBD_StringPrintln(const char str[]){ 344 | int size = strlen(str); 345 | for(int i = 0; i < size; i++){ 346 | CK_USBD_WriteTxCircularBuffer((uint8_t)str[i]); 347 | } 348 | CK_USBD_WriteTxCircularBuffer((uint8_t)10); //for ASCII new line 349 | 350 | } 351 | 352 | void CK_USBD_StringPrint(const char str[]){ 353 | int size = strlen(str); 354 | for(int i = 0; i < size; i++){ 355 | CK_USBD_WriteTxCircularBuffer((uint8_t)str[i]); 356 | } 357 | 358 | } 359 | 360 | 361 | 362 | 363 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/CK_ADF4158.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CK_ADF4158.h" 3 | 4 | #include "CK_SPI.h" 5 | #include "CK_GPIO.h" 6 | #include "CK_TIME_HAL.h" 7 | 8 | #include "math.h" 9 | 10 | #include "CK_CONFIGURATION.h" 11 | 12 | /* 13 | * ADF4158 Freq. Synth. will be used later so not initialize them now. 14 | * PA1 -> ADF_MUXOUT 15 | * PC5 -> ADF_TXDATA (this will be cleared when rf disabled) 16 | * PC4 -> ADF_CE (low disables, high enables adf4158 chip) 17 | * PA2 -> ADF_LE (make it low before write register and high after write, make it high before read) 18 | * PA5 -> ADF_CLK (SPI1_CLK) 19 | * PA7 -> ADF_DATA (SPI1_MOSI) 20 | * 21 | */ 22 | 23 | #define ADF_MUXOUT_GPIO GPIOA 24 | #define ADF_MUXOUT_PIN 1 25 | 26 | #define ADF_MUXOUT_OUTPUT_GPIO GPIOB 27 | #define ADF_MUXOUT_OUTPUT_PIN 8 28 | 29 | #define ADF_TXDATA_GPIO GPIOC 30 | #define ADF_TXDATA_PIN 5 31 | 32 | #define ADF_LE_GPIO GPIOA 33 | #define ADF_LE_PIN 2 34 | 35 | #define ADF_CE_GPIO GPIOC 36 | #define ADF_CE_PIN 4 37 | 38 | #define ADF_SPI SPI1 39 | 40 | #define FREQ_PFD 30000000 41 | 42 | uint32_t muxout_start = 0, muxout_pulse = 0; 43 | int rampStarted = 0, rampCompleted = 0; 44 | 45 | float sweep_period = 0.0f; 46 | 47 | // Default parameters 48 | float waveform_ramp = 1.03e-3; 49 | float waveform_gap = 570e-6; 50 | 51 | void CK_ADF4158_Init(WAVEFORM_TYPE wf){ 52 | 53 | // Read rampDel length high pulse on this pin to know ramp start and end 54 | CK_GPIO_Init(ADF_MUXOUT_GPIO, ADF_MUXOUT_PIN, CK_GPIO_INPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 55 | 56 | // Muxout input signal is outputted to gpio available side of the board to connect to scope easily. 57 | CK_GPIO_Init(ADF_MUXOUT_OUTPUT_GPIO, ADF_MUXOUT_OUTPUT_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 58 | 59 | RCC->APB2ENR |= 1u << 14; // SYSCFG Clock Enable 60 | 61 | // 0u for GPIOA, 1u for GPIOB, 2u for GPIOC 62 | SYSCFG->EXTICR[0] |= (0u << 4); // External interrupt is set to GPIOA Pin1 63 | 64 | EXTI->IMR |= (1u << 1); // Line 1 Interrupt Mask Request 65 | 66 | EXTI->EMR |= (1u << 1); // Line 1 Event Mask Request 67 | 68 | EXTI->RTSR |= (1u << 1); // Rising edge detection for each line 69 | 70 | EXTI->FTSR |= (1u << 1); // Falling edge detection for each line 71 | 72 | //NVIC_SetPriority(EXTI1_IRQn, 0); 73 | 74 | NVIC_EnableIRQ(EXTI1_IRQn); 75 | 76 | CK_GPIO_Init(ADF_TXDATA_GPIO, ADF_TXDATA_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 77 | CK_GPIO_ClearPin(ADF_TXDATA_GPIO, ADF_TXDATA_PIN); 78 | 79 | CK_GPIO_Init(ADF_LE_GPIO, ADF_LE_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 80 | CK_GPIO_SetPin(ADF_LE_GPIO, ADF_LE_PIN); 81 | 82 | CK_GPIO_Init(ADF_CE_GPIO, ADF_CE_PIN, CK_GPIO_OUTPUT, CK_GPIO_NOAF, CK_GPIO_PUSHPULL, CK_GPIO_VERYHIGH, CK_GPIO_NOPUPD); 83 | CK_GPIO_ClearPin(ADF_CE_GPIO, ADF_CE_PIN); 84 | 85 | CK_SPI_Init(ADF_SPI); 86 | 87 | CK_ADF4158_DeviceEnable(); 88 | 89 | float sweep_t = (float)CK_CONFIGURATION_GetSweepTime() / 1000000.0f; 90 | float sweep_g = (float)CK_CONFIGURATION_GetSweepGap() / 1000000.0f; 91 | sweep_period = sweep_t; 92 | 93 | int sweep_gap = (int)(sweep_g * 1000000); 94 | 95 | if(sweep_gap > 4000){ 96 | sweep_gap = 4000; 97 | } 98 | 99 | uint32_t sw_start = CK_CONFIGURATION_GetSweepStartFrequency(); 100 | double sweep_start_freq_ = sw_start * 1e7; 101 | 102 | uint32_t sw_bw = CK_CONFIGURATION_GetSweepBandwith(); 103 | double sweep_bw_ = sw_bw * 1e6; 104 | 105 | int sweep_type = CK_CONFIGURATION_SweepType(); 106 | if(sweep_type == 0){ 107 | wf = SAWTOOTH_WAVEFORM; 108 | } 109 | else{ 110 | wf = TRIANGULAR_WAVEFORM; 111 | } 112 | 113 | CK_ADF4158_Configure_Sweep(wf, sweep_start_freq_, sweep_bw_, sweep_period, sweep_gap); 114 | //CK_ADF4158_Configure_Sweep(SAWTOOTH_WAVEFORM, 5.6e9, 100e6, 1.03e-3, 570); // working 115 | //CK_ADF4158_Configure_Sweep(TRIANGULAR_WAVEFORM, 5.6e9, 100e6, 2.03e-3, 0); // working 116 | 117 | } 118 | 119 | void CK_ADF4158_Configure_Sweep(WAVEFORM_TYPE wf, double startFreq, double bw, double rampTime, int rampDel){ 120 | 121 | // Resolution frequency = FREQ_PFD / 2^25; 122 | double fres = ((double)FREQ_PFD)/(1 << 25); 123 | unsigned int devmax = 1 << 15; 124 | unsigned int clk2 = 1; 125 | 126 | // RFOut = [N + (FRAC / 2^25)] * FREQ_PFD 127 | unsigned int n = startFreq / FREQ_PFD; 128 | unsigned int frac_msb = ((startFreq / FREQ_PFD) - n) * (1 << 12); 129 | unsigned int frac_lsb = ((((startFreq / FREQ_PFD) - n) * (1 << 12)) - frac_msb) * (1 << 13); 130 | 131 | // Datasheet selects freq. resolution and then makes calculations. 132 | // If fdev is selected too small dev_offset becomes a negative number so 0 is asssigned 133 | // and rampDel will not work. "bw / (rampTime * 1000000)" works perfectly with generating gap as selected. 134 | unsigned int fdev = bw / (rampTime * 1000000); 135 | unsigned int steps = bw / fdev; 136 | double timer = rampTime / steps; 137 | unsigned int clk1 = (FREQ_PFD * timer); 138 | 139 | int dev_offset = (int)ceil(log2(fdev/(fres*devmax))); 140 | if(dev_offset < 0){ 141 | dev_offset = 0; 142 | } 143 | 144 | unsigned int dev = fdev/(fres * (1 << dev_offset)); 145 | 146 | uint32_t data = 0; 147 | 148 | // R7 Register 149 | // [18] RAMP DEL FL : '1' ENABLE 150 | // [17] RAMP DEL : '1' ENABLE 151 | // [16] DEL CLK SEL : '1' PFD x CLK1 152 | // [15] DEL ENABLE : '1' ENABLE 153 | // [14:3] DEL 12Bit Word 154 | data = 0; 155 | if(rampDel > 0 && wf == SAWTOOTH_WAVEFORM){ 156 | data |= (1u << 18) | (1u << 17) | (1u << 16) | (1u << 15) | (rampDel << 3) | (7u << 0); 157 | CK_ADF4158_WriteRegister(data); 158 | } 159 | 160 | // R6 Register 161 | // [22:3] STEP WORD : steps 162 | // [2:0] R6 Register control bits : '110' 163 | data = 0; 164 | data |= (steps << 3) | (6u << 0); 165 | CK_ADF4158_WriteRegister(data); 166 | 167 | // R5 Register 168 | // [22:19] DEVIATION OFFSET : dev_offset 169 | // [18:3] DEVIATION WORD: dev 170 | // [2:0] R5 Register control bits : '101' 171 | data = 0; 172 | data |= (dev_offset << 19) | (dev << 3) | (5u << 0); 173 | CK_ADF4158_WriteRegister(data); 174 | 175 | // R4 Register 176 | // [30:26] MODULATOR MODE : DISABLE WHEN FRAC = 0 : '01110' now frac. is used so 0 177 | // [24:23] NEG BLEED CURRENT : ON '11' , OFF '00' with MUX READ BACK 178 | // [22:21] READ BACK TO MUX : ENABLE '11' (Page 30 says 3 not 2) 179 | // [20:19] CLK DIV MODE : RAMP DIVIDER '11' 180 | // [18:7] 12 BIT CLK2 DIVER VALUE : 1 181 | // [2:0] R4 Register control bits : '100' 182 | data = 0; 183 | data |= (0u << 26) | (0u << 23) | (3u << 21) | (3u << 19) | (clk2 << 7) | (4u << 0); 184 | CK_ADF4158_WriteRegister(data); 185 | 186 | // R3 Register 187 | // [11:10] RAMP MODE : Continuous Triangle '01', Continuout Sawtooth '00' 188 | // [2:0] R3 Register control bits : '011' 189 | // [6] Phase detector polarity of VCO : Positive '1' 190 | // [2:0] R3 Register control bits : '011' 191 | data = 0; 192 | if(wf == TRIANGULAR_WAVEFORM){ 193 | data |= (1u << 10); 194 | } 195 | else if(wf == SAWTOOTH_WAVEFORM){ 196 | data |= (0u << 10); 197 | } 198 | data |= (1u << 6) | (3u << 0); 199 | CK_ADF4158_WriteRegister(data); 200 | 201 | // R2 Register 202 | // [28] CSR Enable to improve lock times and removes noise makes waveform perfect. 203 | // [27:24] CP CURRENT SETTING : Icpmax = 25.5 / Rset(5.49K) = 4.65 mA : 14 for Icp 4.69mA 204 | // [22] PRESCALAR : 8/9 '1' for above 3GHz operations 205 | // [21] DIVIDE BY 2 BIT : '0' default 206 | // [20] REFERENCE DOUBLER : '0' default 207 | // [19:15] R COUNTER : 1 208 | // [14:3] CLK1 DIVIDER : clk1 209 | // [2:0] R3 Register control bits : '010' 210 | data = 0; 211 | data |= (1u << 28) | (14u << 24) | (1u << 22) | (1u << 15) | (clk1 << 3) | (2u << 0); 212 | CK_ADF4158_WriteRegister(data); 213 | 214 | // R1 Register 215 | // [27:15] 13 Bit LSB FRAC Value 216 | // [2:0] R1 Register control bits : '001' 217 | data = 0; 218 | data |= (frac_lsb << 15) | (1u << 0); 219 | CK_ADF4158_WriteRegister(data); 220 | 221 | // R0 Register 222 | // [31] RAMP ON : '1' RAMP ENABLE 223 | // [30:27] READ BACK TO MUX : 15 (Generates pulse at MUXOUT pin with R4 READ BACK TO MUX) 224 | // [26:15] 12 BIT INT VALUE : n 225 | // [14:3] 13 Bit MSB FRAC Value 226 | // [2:0] R0 Register control bits : '000' 227 | data = 0; 228 | data |= (1u << 31) | (15u << 27) | (n << 15) | (frac_msb << 3) | (0u << 0); 229 | CK_ADF4158_WriteRegister(data); 230 | 231 | 232 | } 233 | 234 | void CK_ADF4158_WriteRegister(uint32_t data){ 235 | 236 | CK_GPIO_ClearPin(ADF_LE_GPIO, ADF_LE_PIN); 237 | 238 | CK_SPI_Transfer(ADF_SPI, (uint8_t)(data >> 24)); 239 | CK_SPI_Transfer(ADF_SPI, (uint8_t)(data >> 16)); 240 | CK_SPI_Transfer(ADF_SPI, (uint8_t)(data >> 8)); 241 | CK_SPI_Transfer(ADF_SPI, (uint8_t)data); 242 | 243 | CK_GPIO_SetPin(ADF_LE_GPIO, ADF_LE_PIN); 244 | 245 | } 246 | 247 | void CK_ADF4158_DeviceEnable(void){ 248 | 249 | CK_GPIO_SetPin(ADF_CE_GPIO, ADF_CE_PIN); 250 | } 251 | 252 | uint32_t CK_ADF4158_GetPulseReceived(void){ 253 | return muxout_pulse; 254 | } 255 | 256 | // MUXOUT gives high during gap between ramps and low during ramp. 257 | int CK_ADF4158_RampStarted(void){ 258 | return rampStarted; 259 | } 260 | 261 | int CK_ADF4158_RampCompleted(void){ 262 | return rampCompleted; 263 | } 264 | 265 | void EXTI1_IRQHandler(void){ 266 | 267 | if(((ADF_MUXOUT_GPIO->IDR & (1u << ADF_MUXOUT_PIN)) >> ADF_MUXOUT_PIN) == 1){ 268 | 269 | CK_GPIO_SetPin(ADF_MUXOUT_OUTPUT_GPIO, ADF_MUXOUT_OUTPUT_PIN); 270 | 271 | muxout_start = CK_TIME_GetMicroSec(); 272 | 273 | rampCompleted = 1; 274 | rampStarted = 0; 275 | 276 | } 277 | else if(((ADF_MUXOUT_GPIO->IDR & (1u << ADF_MUXOUT_PIN)) >> ADF_MUXOUT_PIN) == 0){ 278 | 279 | CK_GPIO_ClearPin(ADF_MUXOUT_OUTPUT_GPIO, ADF_MUXOUT_OUTPUT_PIN); 280 | 281 | if(muxout_start != 0){ 282 | 283 | muxout_pulse = CK_TIME_GetMicroSec() - muxout_start; 284 | muxout_start = 0; 285 | 286 | rampCompleted = 0; 287 | rampStarted = 1; 288 | 289 | } 290 | } 291 | 292 | EXTI->PR |= 1u << 1; //Clear Interrupt 293 | 294 | } 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | -------------------------------------------------------------------------------- /FMCW_RADAR_Firmware/Core/USBD_CDC/usbd_desc.c: -------------------------------------------------------------------------------- 1 | 2 | #include "USBD_CDC/usbd_core.h" 3 | #include "USBD_CDC/usbd_desc.h" 4 | #include "USBD_CDC/usbd_conf.h" 5 | 6 | #define USBD_VID 1155 7 | #define USBD_LANGID_STRING 1033 8 | #define USBD_MANUFACTURER_STRING "STMicroelectronics" 9 | #define USBD_PID_FS 22336 10 | #define USBD_PRODUCT_STRING_FS "STM32 Virtual ComPort" 11 | #define USBD_CONFIGURATION_STRING_FS "CDC Config" 12 | #define USBD_INTERFACE_STRING_FS "CDC Interface" 13 | 14 | #define USB_SIZ_BOS_DESC 0x0C 15 | 16 | static void Get_SerialNum(void); 17 | static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len); 18 | 19 | uint8_t * USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); 20 | uint8_t * USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); 21 | uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); 22 | uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); 23 | uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); 24 | uint8_t * USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); 25 | uint8_t * USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); 26 | 27 | #ifdef USBD_SUPPORT_USER_STRING_DESC 28 | uint8_t * USBD_FS_USRStringDesc(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); 29 | #endif /* USBD_SUPPORT_USER_STRING_DESC */ 30 | 31 | #if (USBD_LPM_ENABLED == 1) 32 | uint8_t * USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); 33 | #endif /* (USBD_LPM_ENABLED == 1) */ 34 | 35 | USBD_DescriptorsTypeDef FS_Desc = 36 | { 37 | USBD_FS_DeviceDescriptor 38 | , USBD_FS_LangIDStrDescriptor 39 | , USBD_FS_ManufacturerStrDescriptor 40 | , USBD_FS_ProductStrDescriptor 41 | , USBD_FS_SerialStrDescriptor 42 | , USBD_FS_ConfigStrDescriptor 43 | , USBD_FS_InterfaceStrDescriptor 44 | #if (USBD_LPM_ENABLED == 1) 45 | , USBD_FS_USR_BOSDescriptor 46 | #endif /* (USBD_LPM_ENABLED == 1) */ 47 | }; 48 | 49 | #if defined ( __ICCARM__ ) /* IAR Compiler */ 50 | #pragma data_alignment=4 51 | #endif /* defined ( __ICCARM__ ) */ 52 | /** USB standard device descriptor. */ 53 | __ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = 54 | { 55 | 0x12, /*bLength */ 56 | USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ 57 | #if (USBD_LPM_ENABLED == 1) 58 | 0x01, /*bcdUSB */ /* changed to USB version 2.01 59 | in order to support LPM L1 suspend 60 | resume test of USBCV3.0*/ 61 | #else 62 | 0x00, /*bcdUSB */ 63 | #endif /* (USBD_LPM_ENABLED == 1) */ 64 | 0x02, 65 | 0x02, /*bDeviceClass*/ 66 | 0x02, /*bDeviceSubClass*/ 67 | 0x00, /*bDeviceProtocol*/ 68 | USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ 69 | LOBYTE(USBD_VID), /*idVendor*/ 70 | HIBYTE(USBD_VID), /*idVendor*/ 71 | LOBYTE(USBD_PID_FS), /*idProduct*/ 72 | HIBYTE(USBD_PID_FS), /*idProduct*/ 73 | 0x00, /*bcdDevice rel. 2.00*/ 74 | 0x02, 75 | USBD_IDX_MFC_STR, /*Index of manufacturer string*/ 76 | USBD_IDX_PRODUCT_STR, /*Index of product string*/ 77 | USBD_IDX_SERIAL_STR, /*Index of serial number string*/ 78 | USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/ 79 | }; 80 | 81 | /* USB_DeviceDescriptor */ 82 | /** BOS descriptor. */ 83 | #if (USBD_LPM_ENABLED == 1) 84 | #if defined ( __ICCARM__ ) /* IAR Compiler */ 85 | #pragma data_alignment=4 86 | #endif /* defined ( __ICCARM__ ) */ 87 | __ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = 88 | { 89 | 0x5, 90 | USB_DESC_TYPE_BOS, 91 | 0xC, 92 | 0x0, 93 | 0x1, /* 1 device capability*/ 94 | /* device capability*/ 95 | 0x7, 96 | USB_DEVICE_CAPABITY_TYPE, 97 | 0x2, 98 | 0x2, /* LPM capability bit set*/ 99 | 0x0, 100 | 0x0, 101 | 0x0 102 | }; 103 | #endif /* (USBD_LPM_ENABLED == 1) */ 104 | 105 | /** 106 | * @} 107 | */ 108 | 109 | /** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables 110 | * @brief Private variables. 111 | * @{ 112 | */ 113 | 114 | #if defined ( __ICCARM__ ) /* IAR Compiler */ 115 | #pragma data_alignment=4 116 | #endif /* defined ( __ICCARM__ ) */ 117 | 118 | /** USB lang indentifier descriptor. */ 119 | __ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = 120 | { 121 | USB_LEN_LANGID_STR_DESC, 122 | USB_DESC_TYPE_STRING, 123 | LOBYTE(USBD_LANGID_STRING), 124 | HIBYTE(USBD_LANGID_STRING) 125 | }; 126 | 127 | #if defined ( __ICCARM__ ) /* IAR Compiler */ 128 | #pragma data_alignment=4 129 | #endif /* defined ( __ICCARM__ ) */ 130 | /* Internal string descriptor. */ 131 | __ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; 132 | 133 | #if defined ( __ICCARM__ ) /*!< IAR Compiler */ 134 | #pragma data_alignment=4 135 | #endif 136 | __ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = { 137 | USB_SIZ_STRING_SERIAL, 138 | USB_DESC_TYPE_STRING, 139 | }; 140 | 141 | /** 142 | * @} 143 | */ 144 | 145 | /** @defgroup USBD_DESC_Private_Functions USBD_DESC_Private_Functions 146 | * @brief Private functions. 147 | * @{ 148 | */ 149 | 150 | /** 151 | * @brief Return the device descriptor 152 | * @param speed : Current device speed 153 | * @param length : Pointer to data length variable 154 | * @retval Pointer to descriptor buffer 155 | */ 156 | uint8_t * USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) 157 | { 158 | *length = sizeof(USBD_FS_DeviceDesc); 159 | return USBD_FS_DeviceDesc; 160 | } 161 | 162 | /** 163 | * @brief Return the LangID string descriptor 164 | * @param speed : Current device speed 165 | * @param length : Pointer to data length variable 166 | * @retval Pointer to descriptor buffer 167 | */ 168 | uint8_t * USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) 169 | { 170 | *length = sizeof(USBD_LangIDDesc); 171 | return USBD_LangIDDesc; 172 | } 173 | 174 | /** 175 | * @brief Return the product string descriptor 176 | * @param speed : Current device speed 177 | * @param length : Pointer to data length variable 178 | * @retval Pointer to descriptor buffer 179 | */ 180 | uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) 181 | { 182 | if(speed == 0) 183 | { 184 | USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); 185 | } 186 | else 187 | { 188 | USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); 189 | } 190 | return USBD_StrDesc; 191 | } 192 | 193 | /** 194 | * @brief Return the manufacturer string descriptor 195 | * @param speed : Current device speed 196 | * @param length : Pointer to data length variable 197 | * @retval Pointer to descriptor buffer 198 | */ 199 | uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) 200 | { 201 | USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); 202 | return USBD_StrDesc; 203 | } 204 | 205 | /** 206 | * @brief Return the serial number string descriptor 207 | * @param speed : Current device speed 208 | * @param length : Pointer to data length variable 209 | * @retval Pointer to descriptor buffer 210 | */ 211 | uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) 212 | { 213 | *length = USB_SIZ_STRING_SERIAL; 214 | 215 | /* Update the serial number string descriptor with the data from the unique 216 | * ID */ 217 | Get_SerialNum(); 218 | 219 | return (uint8_t *) USBD_StringSerial; 220 | } 221 | 222 | /** 223 | * @brief Return the configuration string descriptor 224 | * @param speed : Current device speed 225 | * @param length : Pointer to data length variable 226 | * @retval Pointer to descriptor buffer 227 | */ 228 | uint8_t * USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) 229 | { 230 | if(speed == USBD_SPEED_HIGH) 231 | { 232 | USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc, length); 233 | } 234 | else 235 | { 236 | USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc, length); 237 | } 238 | return USBD_StrDesc; 239 | } 240 | 241 | /** 242 | * @brief Return the interface string descriptor 243 | * @param speed : Current device speed 244 | * @param length : Pointer to data length variable 245 | * @retval Pointer to descriptor buffer 246 | */ 247 | uint8_t * USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) 248 | { 249 | if(speed == 0) 250 | { 251 | USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc, length); 252 | } 253 | else 254 | { 255 | USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc, length); 256 | } 257 | return USBD_StrDesc; 258 | } 259 | 260 | #if (USBD_LPM_ENABLED == 1) 261 | /** 262 | * @brief Return the BOS descriptor 263 | * @param speed : Current device speed 264 | * @param length : Pointer to data length variable 265 | * @retval Pointer to descriptor buffer 266 | */ 267 | uint8_t * USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) 268 | { 269 | *length = sizeof(USBD_FS_BOSDesc); 270 | return (uint8_t*)USBD_FS_BOSDesc; 271 | } 272 | #endif /* (USBD_LPM_ENABLED == 1) */ 273 | 274 | /** 275 | * @brief Create the serial number string descriptor 276 | * @param None 277 | * @retval None 278 | */ 279 | static void Get_SerialNum(void) 280 | { 281 | uint32_t deviceserial0, deviceserial1, deviceserial2; 282 | 283 | deviceserial0 = *(uint32_t *) DEVICE_ID1; 284 | deviceserial1 = *(uint32_t *) DEVICE_ID2; 285 | deviceserial2 = *(uint32_t *) DEVICE_ID3; 286 | 287 | deviceserial0 += deviceserial2; 288 | 289 | if (deviceserial0 != 0) 290 | { 291 | IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8); 292 | IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4); 293 | } 294 | } 295 | 296 | /** 297 | * @brief Convert Hex 32Bits value into char 298 | * @param value: value to convert 299 | * @param pbuf: pointer to the buffer 300 | * @param len: buffer length 301 | * @retval None 302 | */ 303 | static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len) 304 | { 305 | uint8_t idx = 0; 306 | 307 | for (idx = 0; idx < len; idx++) 308 | { 309 | if (((value >> 28)) < 0xA) 310 | { 311 | pbuf[2 * idx] = (value >> 28) + '0'; 312 | } 313 | else 314 | { 315 | pbuf[2 * idx] = (value >> 28) + 'A' - 10; 316 | } 317 | 318 | value = value << 4; 319 | 320 | pbuf[2 * idx + 1] = 0; 321 | } 322 | } 323 | 324 | --------------------------------------------------------------------------------