Monday, October 5, 2020

STM32 LED Color Matching For Kids

Fun activity for kids with simple LED circuit! The LEDs will light up when the corresponding connectors of the same color are matching.
STM32 Blue Pill (STM32F103C8T6-development-board) circuit connections:
STM32CubeIDE Project:
#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
view raw stm32_leds.ioc hosted with ❤ by GitHub
main.c:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; 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****/
view raw main.c hosted with ❤ by GitHub

Tuesday, April 14, 2020

TVplus Go on Windows 10 PC

Part 2 of TVplus Go on Laptop

Using VirtualBox running Android-x86 guest OS on a Windows 10 PC.
Guides:
1. Android-x86 via VirtualBox
2. Adjust screen resolution. TVplusgo app runs better on 16:9 resolutions (e.g. 1280x720).
3. Enable native bridge (ARM translation layer)
4. Disable root or hide root via Magisk (note: install only v1.0.28 or older of the TVplusgo app).
5. VirtualBox USB pass-through (the official android emulator for Windows, or the Qemu itself, currently does not support USB pass-through).

Tuesday, January 7, 2020

TVplus Go Teardown

Teardown of ABS-CBN TVplus Go USB dongle. This dongle looks like ADTH DGI 1011 (*although the PCB indicates "DGI1012_RevD" instead).



dmesg log when plugged:
[ 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



The USB chip has a marking of "Tolka101" - most probably developed by Tolka Taiwan Inc. - same company who develops the tvplus go app (?). Beside this chip looks like an external EEPROM chip. (*there are no markings on the RF frontend chip).



For simple modification, I replaced the micro-USB connector with an "older" (but more reliable) type-A USB connector+cable - more suitable since I'm using the dongle on laptop or PC more often than my android phone.