/*******************************************************************************
* File Name: main.c
* Description: Interactive LED Controller for PSoC Edge E84
*******************************************************************************/
#include "cybsp.h"
#include "retarget_io_init.h"
/*******************************************************************************
* Macros
*******************************************************************************/
#define CM55_BOOT_WAIT_TIME_USEC (10U)
#define CM55_APP_BOOT_ADDR (CYMEM_CM33_0_m55_nvm_START + \
CYBSP_MCUBOOT_HEADER_SIZE)
/* LED Macros */
#define LED_ON() Cy_GPIO_Set(CYBSP_USER_LED1_PORT, CYBSP_USER_LED1_PIN)
#define LED_OFF() Cy_GPIO_Clr(CYBSP_USER_LED1_PORT, CYBSP_USER_LED1_PIN)
#define LED_TOGGLE() Cy_GPIO_Inv(CYBSP_USER_LED1_PORT, CYBSP_USER_LED1_PIN)
/* Button Macros */
#define USER_BTN_PORT CYBSP_USER_BTN1_PORT
#define USER_BTN_PIN CYBSP_USER_BTN1_PIN
#define DEBOUNCE_DELAY_MS (50U)
#define IS_BUTTON_PRESSED() (Cy_GPIO_Read(USER_BTN_PORT, USER_BTN_PIN) == 0)
/* ADC Configuration */
#define SAR_ADC_INDEX (0U)
#define SAR_ADC_SEQUENCER (0U)
#define SAR_ADC_CHANNEL (0U)
#define SAR_ADC_VREF_MV (1800U)
/*******************************************************************************
* Global Variables
*******************************************************************************/
static bool adc_initialized = false;
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
bool read_button_with_debounce(void);
cy_rslt_t init_adc(void);
int16_t read_potentiometer_mv(void);
uint8_t get_pot_percentage(void);
uint32_t map_pot_to_delay(uint8_t pot_percentage);
/*******************************************************************************
* Function Implementations
*******************************************************************************/
bool read_button_with_debounce(void)
{
static bool last_state = false;
static uint32_t last_press_time = 0;
bool current_state = IS_BUTTON_PRESSED();
uint32_t current_time = Cy_SysLib_GetTimerTick();
if (current_state && !last_state)
{
if ((current_time - last_press_time) > DEBOUNCE_DELAY_MS)
{
last_state = current_state;
last_press_time = current_time;
return true;
}
}
last_state = current_state;
return false;
}
cy_rslt_t init_adc(void)
{
cy_rslt_t result = Cy_AutAnalog_Init(&autonomous_analog_init);
if (CY_AUTANALOG_SUCCESS == result)
{
Cy_AutAnalog_SetInterruptMask(CY_AUTANALOG_INT_SAR0_RESULT);
Cy_AutAnalog_StartAutonomousControl();
adc_initialized = true;
}
return result;
}
int16_t read_potentiometer_mv(void)
{
if (!adc_initialized) return -1;
int32_t adc_count = Cy_AutAnalog_SAR_ReadResult(
SAR_ADC_INDEX, CY_AUTANALOG_SAR_INPUT_GPIO, SAR_ADC_CHANNEL);
return Cy_AutAnalog_SAR_CountsTo_mVolts(
SAR_ADC_INDEX, false, SAR_ADC_SEQUENCER,
CY_AUTANALOG_SAR_INPUT_GPIO, SAR_ADC_CHANNEL,
SAR_ADC_VREF_MV, adc_count);
}
uint8_t get_pot_percentage(void)
{
int16_t mv = read_potentiometer_mv();
if (mv < 0) return 0;
uint8_t pct = (uint8_t)((mv * 100) / SAR_ADC_VREF_MV);
return (pct > 100) ? 100 : pct;
}
uint32_t map_pot_to_delay(uint8_t pot_percentage)
{
uint32_t delay = 1000 - ((uint32_t)pot_percentage * 950 / 100);
return (delay < 50) ? 50 : delay;
}
/*******************************************************************************
* Main Function
*******************************************************************************/
int main(void)
{
cy_rslt_t result;
uint32_t last_led_toggle = 0;
uint32_t last_adc_read = 0;
uint32_t led_delay = 500;
uint8_t mode = 0; /* 0 = normal, 1 = fast */
/* Initialize */
result = cybsp_init();
if (CY_RSLT_SUCCESS != result) handle_app_error();
__enable_irq();
init_retarget_io();
printf("\x1b[2J\x1b[;H");
printf("***********************************************\r\n");
printf("* PSoC Edge: Interactive LED Controller *\r\n");
printf("***********************************************\r\n\n");
init_adc();
Cy_SysEnableCM55(MXCM55, CM55_APP_BOOT_ADDR, CM55_BOOT_WAIT_TIME_USEC);
printf("Controls:\r\n");
printf("- POT: Adjust LED blink speed\r\n");
printf("- Button: Toggle fast mode (2x speed)\r\n\n");
/* Main loop */
for(;;)
{
uint32_t current_time = Cy_SysLib_GetTimerTick();
/* Check button - toggle mode */
if (read_button_with_debounce())
{
mode = !mode;
printf("\rMode: %s \r\n",
mode ? "FAST (2x)" : "NORMAL");
}
/* Read ADC every 100ms */
if ((current_time - last_adc_read) >= 100)
{
last_adc_read = current_time;
uint8_t pot_pct = get_pot_percentage();
led_delay = map_pot_to_delay(pot_pct);
/* Apply fast mode multiplier */
if (mode)
{
led_delay = led_delay / 2;
if (led_delay < 25) led_delay = 25;
}
printf("\rPOT: %3d%% | Delay: %4lu ms | Mode: %s ",
pot_pct, led_delay, mode ? "FAST" : "NORM");
}
/* Toggle LED based on calculated delay */
if ((current_time - last_led_toggle) >= led_delay)
{
last_led_toggle = current_time;
LED_TOGGLE();
}
Cy_SysLib_Delay(10);
}
}