3D-printed Chess Board with Piece Recognition and Connection with Lichess
main controller: ESP32-WROOM w/ OLED display
RFID reader: mini RC522 modules
piece RFID: NTAG213 stickers
diagram:
part 1: Assembly
part 2: Demo
Prototype Projects - experiments on theoretical electronics/electrical designs and actual prototype circuits.
3D-printed Chess Board with Piece Recognition and Connection with Lichess
main controller: ESP32-WROOM w/ OLED display
RFID reader: mini RC522 modules
piece RFID: NTAG213 stickers
diagram:
part 1: Assembly
part 2: Demo
3D-printed WALL-E replica - Wi-Fi controlled using ESP32, with OLED display and audio output.
main controller: ESP32 DEVKIT (with local web server)
motors: 2x 37GB520 (wheels/tracks - driven using TB6612FNG) and 7x MG90S servos
other accessories: 1x OLED display, 1x microSD interface, 1x audio-amplifier
credits:
original 3D design: thingiverse.com/thing:3703555
DIY rechargeable mini-chess-clock using SAMD21 mini board and 0.91" 128x32 OLED display.
Cheap CMSIS-DAP/DAPLink SWD module based on NS32F103CBT6 (an STM32-clone?). It has both a debugger and a serial/UART port on a single USB device just like the J-Link OB v2 debugger (based on STM32F072) - better than those ST-Link debugger clones.
MCU interface:
Firmwares:
(*should work also on chips with smaller ROM STM32F103C8 (like the BluePill C8)
Tested only on Ubuntu host.
sample kernel logs if using original FW:
usb 1-1: new full-speed USB device number 44 using xhci_hcd
usb 1-1: New USB device found, idVendor=c251, idProduct=f001, bcdDevice= 1.00
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: CMSIS_DAP
usb 1-1: Manufacturer: CMSIS-DAP by ARM
usb 1-1: SerialNumber: 202108120001
cdc_acm 1-1:1.0: ttyACM0: USB ACM device
hid-generic 0003:C251:F001.0015: hiddev0,hidraw2: USB HID v1.00 Device [CMSIS-DAP by ARM CMSIS_DAP] on usb-0000:00:14.0-1/input2
Sample kernel logs if using the modified FW:
usb 1-1: new full-speed USB device number 52 using xhci_hcd
usb 1-1: device descriptor read/64, error -71
usb 1-1: new full-speed USB device number 53 using xhci_hcd
usb 1-1: New USB device found, idVendor=0d28, idProduct=0204, bcdDevice= 1.00
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: DAPLink CMSIS-DAP
usb 1-1: Manufacturer: ARM
usb 1-1: SerialNumber: 20220218979699080605210b3030153632303030
cdc_acm 1-1:1.0: ttyACM0: USB ACM device
usbcore: registered new interface driver cdc_acm
usbhid 1-1:1.2: couldn't find an input interrupt endpoint
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
Sample openocd configuration:
source [find interface/cmsis-dap.cfg]If using the original FW, need to add these on the configuration:
transport select swd
source [find target/stm32f4x.cfg]
adapter speed 4000
init
targets
reset halt
cmsis_dap_vid_pid 0xc251 0xf001
cmsis_dap_backend hid
Not tested:
size comparison (from left to right) :
Reference:
#MicroXplorer Configuration settings - do not modify | |
FREERTOS.IPParameters=Tasks01 | |
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL | |
File.Version=6 | |
KeepUserPlacement=false | |
Mcu.Family=STM32F1 | |
Mcu.IP0=FREERTOS | |
Mcu.IP1=NVIC | |
Mcu.IP2=RCC | |
Mcu.IP3=SYS | |
Mcu.IPNb=4 | |
Mcu.Name=STM32F103C(8-B)Tx | |
Mcu.Package=LQFP48 | |
Mcu.Pin0=PC13-TAMPER-RTC | |
Mcu.Pin1=PD0-OSC_IN | |
Mcu.Pin10=PB12 | |
Mcu.Pin11=PB13 | |
Mcu.Pin12=PB14 | |
Mcu.Pin13=PA13 | |
Mcu.Pin14=PA14 | |
Mcu.Pin15=PB3 | |
Mcu.Pin16=PB4 | |
Mcu.Pin17=PB5 | |
Mcu.Pin18=PB6 | |
Mcu.Pin19=PB7 | |
Mcu.Pin2=PD1-OSC_OUT | |
Mcu.Pin20=VP_FREERTOS_VS_CMSIS_V2 | |
Mcu.Pin21=VP_SYS_VS_ND | |
Mcu.Pin22=VP_SYS_VS_tim1 | |
Mcu.Pin3=PA0-WKUP | |
Mcu.Pin4=PA1 | |
Mcu.Pin5=PA2 | |
Mcu.Pin6=PA3 | |
Mcu.Pin7=PA4 | |
Mcu.Pin8=PB10 | |
Mcu.Pin9=PB11 | |
Mcu.PinsNb=23 | |
Mcu.ThirdPartyNb=0 | |
Mcu.UserConstants= | |
Mcu.UserName=STM32F103C8Tx | |
MxCube.Version=6.0.0 | |
MxDb.Version=DB.6.0.0 | |
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false | |
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false | |
NVIC.ForceEnableDMAVector=true | |
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false | |
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false | |
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false | |
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false | |
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 | |
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false | |
NVIC.SavedPendsvIrqHandlerGenerated=true | |
NVIC.SavedSvcallIrqHandlerGenerated=true | |
NVIC.SavedSystickIrqHandlerGenerated=true | |
NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false | |
NVIC.TIM1_UP_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true | |
NVIC.TimeBase=TIM1_UP_IRQn | |
NVIC.TimeBaseIP=TIM1 | |
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false | |
PA0-WKUP.GPIOParameters=GPIO_Label | |
PA0-WKUP.GPIO_Label=OUT_BLUE | |
PA0-WKUP.Locked=true | |
PA0-WKUP.Signal=GPIO_Output | |
PA1.GPIOParameters=GPIO_Label | |
PA1.GPIO_Label=OUT_YELLOW | |
PA1.Locked=true | |
PA1.Signal=GPIO_Output | |
PA13.Locked=true | |
PA13.Signal=SYS_JTMS-SWDIO | |
PA14.Locked=true | |
PA14.Signal=SYS_JTCK-SWCLK | |
PA2.GPIOParameters=GPIO_Label | |
PA2.GPIO_Label=OUT_RED | |
PA2.Locked=true | |
PA2.Signal=GPIO_Output | |
PA3.GPIOParameters=GPIO_Label | |
PA3.GPIO_Label=OUT_WHITE | |
PA3.Locked=true | |
PA3.Signal=GPIO_Output | |
PA4.GPIOParameters=GPIO_Label | |
PA4.GPIO_Label=OUT_GREEN | |
PA4.Locked=true | |
PA4.Signal=GPIO_Output | |
PB10.GPIOParameters=GPIO_Label | |
PB10.GPIO_Label=LED_WHITE | |
PB10.Locked=true | |
PB10.Signal=GPIO_Output | |
PB11.GPIOParameters=GPIO_Label | |
PB11.GPIO_Label=LED_YELLOW | |
PB11.Locked=true | |
PB11.Signal=GPIO_Output | |
PB12.GPIOParameters=GPIO_Label | |
PB12.GPIO_Label=LED_BLUE | |
PB12.Locked=true | |
PB12.Signal=GPIO_Output | |
PB13.GPIOParameters=GPIO_Label | |
PB13.GPIO_Label=LED_GREEN | |
PB13.Locked=true | |
PB13.Signal=GPIO_Output | |
PB14.GPIOParameters=GPIO_Label | |
PB14.GPIO_Label=LED_RED | |
PB14.Locked=true | |
PB14.Signal=GPIO_Output | |
PB3.GPIOParameters=GPIO_PuPd,GPIO_Label | |
PB3.GPIO_Label=IN_WHITE | |
PB3.GPIO_PuPd=GPIO_PULLUP | |
PB3.Locked=true | |
PB3.Signal=GPIO_Input | |
PB4.GPIOParameters=GPIO_PuPd,GPIO_Label | |
PB4.GPIO_Label=IN_YELLOW | |
PB4.GPIO_PuPd=GPIO_PULLUP | |
PB4.Locked=true | |
PB4.Signal=GPIO_Input | |
PB5.GPIOParameters=GPIO_PuPd,GPIO_Label | |
PB5.GPIO_Label=IN_BLUE | |
PB5.GPIO_PuPd=GPIO_PULLUP | |
PB5.Locked=true | |
PB5.Signal=GPIO_Input | |
PB6.GPIOParameters=GPIO_PuPd,GPIO_Label | |
PB6.GPIO_Label=IN_GREEN | |
PB6.GPIO_PuPd=GPIO_PULLUP | |
PB6.Locked=true | |
PB6.Signal=GPIO_Input | |
PB7.GPIOParameters=GPIO_PuPd,GPIO_Label | |
PB7.GPIO_Label=IN_RED | |
PB7.GPIO_PuPd=GPIO_PULLUP | |
PB7.Locked=true | |
PB7.Signal=GPIO_Input | |
PC13-TAMPER-RTC.GPIOParameters=GPIO_Label | |
PC13-TAMPER-RTC.GPIO_Label=LED_PC13 | |
PC13-TAMPER-RTC.Locked=true | |
PC13-TAMPER-RTC.Signal=GPIO_Output | |
PD0-OSC_IN.Mode=HSE-External-Oscillator | |
PD0-OSC_IN.Signal=RCC_OSC_IN | |
PD1-OSC_OUT.Mode=HSE-External-Oscillator | |
PD1-OSC_OUT.Signal=RCC_OSC_OUT | |
PinOutPanel.RotationAngle=0 | |
ProjectManager.AskForMigrate=true | |
ProjectManager.BackupPrevious=false | |
ProjectManager.CompilerOptimize=6 | |
ProjectManager.ComputerToolchain=false | |
ProjectManager.CoupleFile=false | |
ProjectManager.CustomerFirmwarePackage= | |
ProjectManager.DefaultFWLocation=true | |
ProjectManager.DeletePrevious=true | |
ProjectManager.DeviceId=STM32F103C8Tx | |
ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.8.2 | |
ProjectManager.FreePins=false | |
ProjectManager.HalAssertFull=false | |
ProjectManager.HeapSize=0x200 | |
ProjectManager.KeepUserCode=true | |
ProjectManager.LastFirmware=true | |
ProjectManager.LibraryCopy=1 | |
ProjectManager.MainLocation=Core/Src | |
ProjectManager.NoMain=false | |
ProjectManager.PreviousToolchain= | |
ProjectManager.ProjectBuild=false | |
ProjectManager.ProjectFileName=stm32_leds.ioc | |
ProjectManager.ProjectName=stm32_leds | |
ProjectManager.RegisterCallBack= | |
ProjectManager.StackSize=0x400 | |
ProjectManager.TargetToolchain=STM32CubeIDE | |
ProjectManager.ToolChainLocation= | |
ProjectManager.UnderRoot=true | |
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false | |
RCC.ADCFreqValue=36000000 | |
RCC.AHBFreq_Value=72000000 | |
RCC.APB1CLKDivider=RCC_HCLK_DIV2 | |
RCC.APB1Freq_Value=36000000 | |
RCC.APB1TimFreq_Value=72000000 | |
RCC.APB2Freq_Value=72000000 | |
RCC.APB2TimFreq_Value=72000000 | |
RCC.FCLKCortexFreq_Value=72000000 | |
RCC.FamilyName=M | |
RCC.HCLKFreq_Value=72000000 | |
RCC.IPParameters=ADCFreqValue,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,PLLSourceVirtual,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value,VCOOutput2Freq_Value | |
RCC.MCOFreq_Value=72000000 | |
RCC.PLLCLKFreq_Value=72000000 | |
RCC.PLLMCOFreq_Value=36000000 | |
RCC.PLLMUL=RCC_PLL_MUL9 | |
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE | |
RCC.SYSCLKFreq_VALUE=72000000 | |
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK | |
RCC.TimSysFreq_Value=72000000 | |
RCC.USBFreq_Value=72000000 | |
RCC.VCOOutput2Freq_Value=8000000 | |
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2 | |
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2 | |
VP_SYS_VS_ND.Mode=No_Debug | |
VP_SYS_VS_ND.Signal=SYS_VS_ND | |
VP_SYS_VS_tim1.Mode=TIM1 | |
VP_SYS_VS_tim1.Signal=SYS_VS_tim1 | |
board=custom | |
isbadioc=false |
/* USER CODE BEGIN Header */ | |
/** | |
****************************************************************************** | |
* @file : main.c | |
* @brief : Main program body | |
****************************************************************************** | |
* @attention | |
* | |
* <h2><center>© Copyright (c) 2020 STMicroelectronics. | |
* All rights reserved.</center></h2> | |
* | |
* This software component is licensed by ST under BSD 3-Clause license, | |
* the "License"; You may not use this file except in compliance with the | |
* License. You may obtain a copy of the License at: | |
* opensource.org/licenses/BSD-3-Clause | |
* | |
****************************************************************************** | |
*/ | |
/* USER CODE END Header */ | |
/* Includes ------------------------------------------------------------------*/ | |
#include "main.h" | |
#include "cmsis_os.h" | |
/* Private includes ----------------------------------------------------------*/ | |
/* USER CODE BEGIN Includes */ | |
/* USER CODE END Includes */ | |
/* Private typedef -----------------------------------------------------------*/ | |
/* USER CODE BEGIN PTD */ | |
typedef enum { | |
COLOR_RED = 0, | |
COLOR_GREEN = 1, | |
COLOR_BLUE = 2 , | |
COLOR_YELLOW = 3, | |
COLOR_WHITE = 4, | |
COLOR_UNKNOWN | |
} led_color_et; | |
/* USER CODE END PTD */ | |
/* Private define ------------------------------------------------------------*/ | |
/* USER CODE BEGIN PD */ | |
#define LEDS_ALL ((1<<COLOR_RED) | (1<<COLOR_GREEN) | (1<<COLOR_BLUE) | (1<<COLOR_YELLOW) | (1<<COLOR_WHITE)) | |
/* USER CODE END PD */ | |
/* Private macro -------------------------------------------------------------*/ | |
/* USER CODE BEGIN PM */ | |
#define LED_ON(led) HAL_GPIO_WritePin(LED_ ## led ## _GPIO_Port, LED_ ## led ## _Pin, GPIO_PIN_SET) | |
#define LED_OFF(led) HAL_GPIO_WritePin(LED_ ## led ## _GPIO_Port, LED_ ## led ## _Pin, GPIO_PIN_RESET) | |
#define LED_TOGGLE(led) HAL_GPIO_TogglePin(LED_ ## led ## _GPIO_Port, LED_ ## led ## _Pin) | |
#define OUT_HIGH(out) HAL_GPIO_WritePin(OUT_ ## out ## _GPIO_Port, OUT_ ## out ## _Pin, GPIO_PIN_SET) | |
#define OUT_LOW(out) HAL_GPIO_WritePin(OUT_ ## out ## _GPIO_Port, OUT_ ## out ## _Pin, GPIO_PIN_RESET) | |
#define IN_IS_HIGH(in) (GPIO_PIN_SET == HAL_GPIO_ReadPin(IN_ ## in ## _GPIO_Port, IN_ ## in ## _Pin)) | |
#define IN_IS_LOW(in) (GPIO_PIN_RESET == HAL_GPIO_ReadPin(IN_ ## in ## _GPIO_Port, IN_ ## in ## _Pin)) | |
/* USER CODE END PM */ | |
/* Private variables ---------------------------------------------------------*/ | |
/* Definitions for defaultTask */ | |
osThreadId_t defaultTaskHandle; | |
const osThreadAttr_t defaultTask_attributes = { | |
.name = "defaultTask", | |
.priority = (osPriority_t) osPriorityNormal, | |
.stack_size = 128 * 4 | |
}; | |
/* USER CODE BEGIN PV */ | |
/* USER CODE END PV */ | |
/* Private function prototypes -----------------------------------------------*/ | |
void SystemClock_Config(void); | |
static void MX_GPIO_Init(void); | |
void StartDefaultTask(void *argument); | |
/* USER CODE BEGIN PFP */ | |
/* USER CODE END PFP */ | |
/* Private user code ---------------------------------------------------------*/ | |
/* USER CODE BEGIN 0 */ | |
static uint32_t scan_matched_colors(void) | |
{ | |
uint32_t matched = 0; | |
// red | |
OUT_LOW(RED); | |
osDelay(1); | |
if (IN_IS_LOW(RED)) { | |
matched |= (1 << COLOR_RED); | |
} | |
OUT_HIGH(RED); | |
// green | |
OUT_LOW(GREEN); | |
osDelay(1); | |
if (IN_IS_LOW(GREEN)) { | |
matched |= (1 << COLOR_GREEN); | |
} | |
OUT_HIGH(GREEN); | |
// blue | |
OUT_LOW(BLUE); | |
osDelay(1); | |
if (IN_IS_LOW(BLUE)) { | |
matched |= (1 << COLOR_BLUE); | |
} | |
OUT_HIGH(BLUE); | |
// yellow | |
OUT_LOW(YELLOW); | |
osDelay(1); | |
if (IN_IS_LOW(YELLOW)) { | |
matched |= (1 << COLOR_YELLOW); | |
} | |
OUT_HIGH(YELLOW); | |
// white | |
OUT_LOW(WHITE); | |
osDelay(1); | |
if (IN_IS_LOW(WHITE)) { | |
matched |= (1 << COLOR_WHITE); | |
} | |
OUT_HIGH(WHITE); | |
return matched; | |
} | |
static void run_leds(void) | |
{ | |
static led_color_et e_led = COLOR_RED; | |
static uint32_t last_run = 0; | |
if (osKernelGetTickCount() - last_run < 200) { | |
return; | |
} | |
last_run = osKernelGetTickCount(); | |
switch (e_led) | |
{ | |
case COLOR_RED: | |
LED_ON(RED); | |
LED_OFF(GREEN); | |
LED_OFF(BLUE); | |
LED_OFF(YELLOW); | |
LED_OFF(WHITE); | |
break; | |
case COLOR_GREEN: | |
LED_ON(GREEN); | |
LED_OFF(RED); | |
LED_OFF(BLUE); | |
LED_OFF(YELLOW); | |
LED_OFF(WHITE); | |
break; | |
case COLOR_BLUE: | |
LED_ON(BLUE); | |
LED_OFF(RED); | |
LED_OFF(GREEN); | |
LED_OFF(YELLOW); | |
LED_OFF(WHITE); | |
break; | |
case COLOR_YELLOW: | |
LED_ON(YELLOW); | |
LED_OFF(RED); | |
LED_OFF(GREEN); | |
LED_OFF(BLUE); | |
LED_OFF(WHITE); | |
break; | |
//case COLOR_WHITE: | |
default: | |
LED_ON(WHITE); | |
LED_OFF(RED); | |
LED_OFF(GREEN); | |
LED_OFF(BLUE); | |
LED_OFF(YELLOW); | |
e_led = COLOR_RED; | |
return; | |
} | |
e_led++; | |
} | |
/* USER CODE END 0 */ | |
/** | |
* @brief The application entry point. | |
* @retval int | |
*/ | |
int main(void) | |
{ | |
/* USER CODE BEGIN 1 */ | |
/* USER CODE END 1 */ | |
/* MCU Configuration--------------------------------------------------------*/ | |
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ | |
HAL_Init(); | |
/* USER CODE BEGIN Init */ | |
/* USER CODE END Init */ | |
/* Configure the system clock */ | |
SystemClock_Config(); | |
/* USER CODE BEGIN SysInit */ | |
/* USER CODE END SysInit */ | |
/* Initialize all configured peripherals */ | |
MX_GPIO_Init(); | |
/* USER CODE BEGIN 2 */ | |
/* USER CODE END 2 */ | |
/* Init scheduler */ | |
osKernelInitialize(); | |
/* USER CODE BEGIN RTOS_MUTEX */ | |
/* add mutexes, ... */ | |
/* USER CODE END RTOS_MUTEX */ | |
/* USER CODE BEGIN RTOS_SEMAPHORES */ | |
/* add semaphores, ... */ | |
/* USER CODE END RTOS_SEMAPHORES */ | |
/* USER CODE BEGIN RTOS_TIMERS */ | |
/* start timers, add new ones, ... */ | |
/* USER CODE END RTOS_TIMERS */ | |
/* USER CODE BEGIN RTOS_QUEUES */ | |
/* add queues, ... */ | |
/* USER CODE END RTOS_QUEUES */ | |
/* Create the thread(s) */ | |
/* creation of defaultTask */ | |
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes); | |
/* USER CODE BEGIN RTOS_THREADS */ | |
/* add threads, ... */ | |
/* USER CODE END RTOS_THREADS */ | |
/* Start scheduler */ | |
osKernelStart(); | |
/* We should never get here as control is now taken by the scheduler */ | |
/* Infinite loop */ | |
/* USER CODE BEGIN WHILE */ | |
while (1) | |
{ | |
/* USER CODE END WHILE */ | |
/* USER CODE BEGIN 3 */ | |
} | |
/* USER CODE END 3 */ | |
} | |
/** | |
* @brief System Clock Configuration | |
* @retval None | |
*/ | |
void SystemClock_Config(void) | |
{ | |
RCC_OscInitTypeDef RCC_OscInitStruct = {0}; | |
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; | |
/** Initializes the RCC Oscillators according to the specified parameters | |
* in the RCC_OscInitTypeDef structure. | |
*/ | |
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; | |
RCC_OscInitStruct.HSEState = RCC_HSE_ON; | |
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; | |
RCC_OscInitStruct.HSIState = RCC_HSI_ON; | |
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; | |
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; | |
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; | |
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) | |
{ | |
Error_Handler(); | |
} | |
/** Initializes the CPU, AHB and APB buses clocks | |
*/ | |
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK | |
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; | |
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; | |
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; | |
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; | |
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; | |
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) | |
{ | |
Error_Handler(); | |
} | |
} | |
/** | |
* @brief GPIO Initialization Function | |
* @param None | |
* @retval None | |
*/ | |
static void MX_GPIO_Init(void) | |
{ | |
GPIO_InitTypeDef GPIO_InitStruct = {0}; | |
/* GPIO Ports Clock Enable */ | |
__HAL_RCC_GPIOC_CLK_ENABLE(); | |
__HAL_RCC_GPIOD_CLK_ENABLE(); | |
__HAL_RCC_GPIOA_CLK_ENABLE(); | |
__HAL_RCC_GPIOB_CLK_ENABLE(); | |
/*Configure GPIO pin Output Level */ | |
HAL_GPIO_WritePin(LED_PC13_GPIO_Port, LED_PC13_Pin, GPIO_PIN_RESET); | |
/*Configure GPIO pin Output Level */ | |
HAL_GPIO_WritePin(GPIOA, OUT_BLUE_Pin|OUT_YELLOW_Pin|OUT_RED_Pin|OUT_WHITE_Pin | |
|OUT_GREEN_Pin, GPIO_PIN_RESET); | |
/*Configure GPIO pin Output Level */ | |
HAL_GPIO_WritePin(GPIOB, LED_WHITE_Pin|LED_YELLOW_Pin|LED_BLUE_Pin|LED_GREEN_Pin | |
|LED_RED_Pin, GPIO_PIN_RESET); | |
/*Configure GPIO pin : LED_PC13_Pin */ | |
GPIO_InitStruct.Pin = LED_PC13_Pin; | |
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; | |
GPIO_InitStruct.Pull = GPIO_NOPULL; | |
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; | |
HAL_GPIO_Init(LED_PC13_GPIO_Port, &GPIO_InitStruct); | |
/*Configure GPIO pins : OUT_BLUE_Pin OUT_YELLOW_Pin OUT_RED_Pin OUT_WHITE_Pin | |
OUT_GREEN_Pin */ | |
GPIO_InitStruct.Pin = OUT_BLUE_Pin|OUT_YELLOW_Pin|OUT_RED_Pin|OUT_WHITE_Pin | |
|OUT_GREEN_Pin; | |
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; | |
GPIO_InitStruct.Pull = GPIO_NOPULL; | |
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; | |
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); | |
/*Configure GPIO pins : LED_WHITE_Pin LED_YELLOW_Pin LED_BLUE_Pin LED_GREEN_Pin | |
LED_RED_Pin */ | |
GPIO_InitStruct.Pin = LED_WHITE_Pin|LED_YELLOW_Pin|LED_BLUE_Pin|LED_GREEN_Pin | |
|LED_RED_Pin; | |
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; | |
GPIO_InitStruct.Pull = GPIO_NOPULL; | |
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; | |
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); | |
/*Configure GPIO pins : IN_WHITE_Pin IN_YELLOW_Pin IN_BLUE_Pin IN_GREEN_Pin | |
IN_RED_Pin */ | |
GPIO_InitStruct.Pin = IN_WHITE_Pin|IN_YELLOW_Pin|IN_BLUE_Pin|IN_GREEN_Pin | |
|IN_RED_Pin; | |
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; | |
GPIO_InitStruct.Pull = GPIO_PULLUP; | |
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); | |
} | |
/* USER CODE BEGIN 4 */ | |
/* USER CODE END 4 */ | |
/* USER CODE BEGIN Header_StartDefaultTask */ | |
/** | |
* @brief Function implementing the defaultTask thread. | |
* @param argument: Not used | |
* @retval None | |
*/ | |
/* USER CODE END Header_StartDefaultTask */ | |
void StartDefaultTask(void *argument) | |
{ | |
/* USER CODE BEGIN 5 */ | |
#if 0 | |
LED_ON(GREEN); | |
LED_ON(YELLOW); | |
#else | |
uint32_t last_tick = osKernelGetTickCount(); | |
uint32_t matched_colors = 0; | |
#endif | |
/* Infinite loop */ | |
for(;;) | |
{ | |
#if 0 | |
LED_TOGGLE(RED); | |
LED_TOGGLE(GREEN); | |
LED_TOGGLE(BLUE); | |
LED_TOGGLE(YELLOW); | |
LED_TOGGLE(WHITE); | |
osDelay(500); | |
#else | |
matched_colors = scan_matched_colors(); | |
if (LEDS_ALL == matched_colors) { | |
run_leds(); | |
} | |
else | |
{ | |
if (matched_colors & (1 << COLOR_RED)) { | |
LED_ON(RED); | |
} else { | |
LED_OFF(RED); | |
} | |
if (matched_colors & (1 << COLOR_GREEN)) { | |
LED_ON(GREEN); | |
} else { | |
LED_OFF(GREEN); | |
} | |
if (matched_colors & (1 << COLOR_BLUE)) { | |
LED_ON(BLUE); | |
} else { | |
LED_OFF(BLUE); | |
} | |
if (matched_colors & (1 << COLOR_YELLOW)) { | |
LED_ON(YELLOW); | |
} else { | |
LED_OFF(YELLOW); | |
} | |
if (matched_colors & (1 << COLOR_WHITE)) { | |
LED_ON(WHITE); | |
} else { | |
LED_OFF(WHITE); | |
} | |
} | |
if (osKernelGetTickCount() - last_tick >= 500) { | |
last_tick = osKernelGetTickCount(); | |
LED_TOGGLE(PC13); | |
} | |
#endif | |
} | |
/* USER CODE END 5 */ | |
} | |
/** | |
* @brief Period elapsed callback in non blocking mode | |
* @note This function is called when TIM1 interrupt took place, inside | |
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment | |
* a global variable "uwTick" used as application time base. | |
* @param htim : TIM handle | |
* @retval None | |
*/ | |
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) | |
{ | |
/* USER CODE BEGIN Callback 0 */ | |
/* USER CODE END Callback 0 */ | |
if (htim->Instance == TIM1) { | |
HAL_IncTick(); | |
} | |
/* USER CODE BEGIN Callback 1 */ | |
/* USER CODE END Callback 1 */ | |
} | |
/** | |
* @brief This function is executed in case of error occurrence. | |
* @retval None | |
*/ | |
void Error_Handler(void) | |
{ | |
/* USER CODE BEGIN Error_Handler_Debug */ | |
/* User can add his own implementation to report the HAL error return state */ | |
/* USER CODE END Error_Handler_Debug */ | |
} | |
#ifdef USE_FULL_ASSERT | |
/** | |
* @brief Reports the name of the source file and the source line number | |
* where the assert_param error has occurred. | |
* @param file: pointer to the source file name | |
* @param line: assert_param error line source number | |
* @retval None | |
*/ | |
void assert_failed(uint8_t *file, uint32_t line) | |
{ | |
/* USER CODE BEGIN 6 */ | |
/* User can add his own implementation to report the file name and line number, | |
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ | |
/* USER CODE END 6 */ | |
} | |
#endif /* USE_FULL_ASSERT */ | |
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
[ 2555.447630] usb 1-1: new high-speed USB device number 13 using xhci_hcd [ 2555.601320] usb 1-1: New USB device found, idVendor=048d, idProduct=9308, bcdDevice= 1.00 [ 2555.601325] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 2555.601329] usb 1-1: Product: DGI1011 [ 2555.601331] usb 1-1: Manufacturer: Atlanta DTH, Inc. [ 2555.601333] usb 1-1: SerialNumber: 000000