This commit is contained in:
sherlock 2025-10-23 12:58:06 +05:30
parent e36e851593
commit 0fc16cc75f

View file

@ -1,24 +1,21 @@
#include "LPC17xx.h" #include "LPC17xx.h"
// PWM variables volatile unsigned long int duty_cycle = 10;
volatile unsigned long int duty_cycle = 10; // Start at 10%
volatile unsigned long int pwm_counter = 0; volatile unsigned long int pwm_counter = 0;
// Pin definitions #define LED_SHIFT 4
#define LED_SHIFT 4 // CNA: P0.4-P0.11
#define LED_MASK (0xFF << LED_SHIFT) #define LED_MASK (0xFF << LED_SHIFT)
// Keypad on CND - ROW-0 #define COL0 (1<<0)
#define COL0 (1<<0) // P2.0 #define COL1 (1<<1)
#define COL1 (1<<1) // P2.1 #define COL2 (1<<23)
#define COL2 (1<<23) // P0.23 #define COL3 (1<<24)
#define COL3 (1<<24) // P0.24 #define ROW0 (1<<25)
#define ROW0 (1<<25) // P0.25
#define COL_MASK_P0 (COL2 | COL3) #define COL_MASK_P0 (COL2 | COL3)
#define COL_MASK_P2 (COL0 | COL1) #define COL_MASK_P2 (COL0 | COL1)
#define PWM_PERIOD 100 // 100 steps for percentage #define PWM_PERIOD 100
static void delay_ms(unsigned int ms) { static void delay_ms(unsigned int ms) {
unsigned int i, j; unsigned int i, j;
@ -44,22 +41,20 @@ static unsigned int is_row0_pressed(void)
return !(LPC_GPIO0->FIOPIN & ROW0); return !(LPC_GPIO0->FIOPIN & ROW0);
} }
// HIGH-SPEED PWM Interrupt Handler
void PWM1_IRQHandler(void) void PWM1_IRQHandler(void)
{ {
if (LPC_PWM1->IR & (1 << 0)) if (LPC_PWM1->IR & (1 << 0))
{ {
// Fast software PWM for all 8 LEDs
if(pwm_counter < duty_cycle) if(pwm_counter < duty_cycle)
LPC_GPIO0->FIOSET = LED_MASK; // All LEDs ON LPC_GPIO0->FIOSET = LED_MASK;
else else
LPC_GPIO0->FIOCLR = LED_MASK; // All LEDs OFF LPC_GPIO0->FIOCLR = LED_MASK;
pwm_counter++; pwm_counter++;
if(pwm_counter >= PWM_PERIOD) if(pwm_counter >= PWM_PERIOD)
pwm_counter = 0; pwm_counter = 0;
LPC_PWM1->IR = (1 << 0); // Clear interrupt flag LPC_PWM1->IR = (1 << 0);
} }
} }
@ -69,58 +64,46 @@ int main(void)
unsigned int read_key; unsigned int read_key;
unsigned int last_key = 0xFF; unsigned int last_key = 0xFF;
// === PIN CONFIGURATION === LPC_PINCON->PINSEL0 &= ~(0xFFFF << 8);
LPC_PINCON->PINSEL0 &= ~(0xFFFF << 8); // P0.4-P0.11 as GPIO LPC_PINCON->PINSEL1 &= ~(0xFFFF << 14);
LPC_PINCON->PINSEL1 &= ~(0xFFFF << 14); // P0.23-P0.28 as GPIO LPC_PINCON->PINSEL4 &= ~(0xF << 0);
LPC_PINCON->PINSEL4 &= ~(0xF << 0); // P2.0-P2.1 as GPIO
// === GPIO SETUP === LPC_GPIO0->FIODIR |= LED_MASK;
LPC_GPIO0->FIODIR |= LED_MASK; // LEDs output LPC_GPIO0->FIODIR |= COL_MASK_P0;
LPC_GPIO0->FIODIR |= COL_MASK_P0; // Columns output LPC_GPIO2->FIODIR |= COL_MASK_P2;
LPC_GPIO2->FIODIR |= COL_MASK_P2; // Columns output LPC_GPIO0->FIODIR &= ~ROW0;
LPC_GPIO0->FIODIR &= ~ROW0; // Row input
// Initialize
LPC_GPIO0->FIOCLR = LED_MASK; LPC_GPIO0->FIOCLR = LED_MASK;
LPC_GPIO2->FIOSET = COL_MASK_P2; LPC_GPIO2->FIOSET = COL_MASK_P2;
LPC_GPIO0->FIOSET = COL_MASK_P0; LPC_GPIO0->FIOSET = COL_MASK_P0;
// === HIGH-SPEED PWM CONFIGURATION === LPC_SC->PCONP |= (1 << 6);
LPC_SC->PCONP |= (1 << 6); // Power on PWM1
LPC_PWM1->TCR = (1 << 1); // Reset LPC_PWM1->TCR = (1 << 1);
LPC_PWM1->CTCR = 0; // Timer mode LPC_PWM1->CTCR = 0;
LPC_PWM1->PR = 9; // Prescaler = 10 LPC_PWM1->PR = 9;
// 100MHz / 10 = 10MHz timer clock
LPC_PWM1->MR0 = 100; // Match every 100 ticks LPC_PWM1->MR0 = 100;
// Interrupt rate = 10MHz/100 = 100kHz LPC_PWM1->MCR = (1 << 1) | (1 << 0);
// PWM frequency = 100kHz/100 = 1kHz LPC_PWM1->LER = (1 << 0);
// NO VISIBLE FLICKER!
LPC_PWM1->MCR = (1 << 1) | (1 << 0); // Reset on MR0 + interrupt NVIC_EnableIRQ(PWM1_IRQn);
LPC_PWM1->LER = (1 << 0); // Latch MR0 NVIC_SetPriority(PWM1_IRQn, 0);
NVIC_EnableIRQ(PWM1_IRQn); // Enable interrupt LPC_PWM1->TCR = (1 << 0) | (1 << 3);
NVIC_SetPriority(PWM1_IRQn, 0); // Highest priority
LPC_PWM1->TCR = (1 << 0) | (1 << 3); // Start PWM
// === MAIN LOOP ===
while(1) while(1)
{ {
read_key = 0xFF; read_key = 0xFF;
// Scan ROW-0 only
for(col_idx = 0; col_idx < 4; col_idx++) for(col_idx = 0; col_idx < 4; col_idx++)
{ {
set_column(col_idx); set_column(col_idx);
delay_ms(5); // Short delay for stable reading delay_ms(5);
if(is_row0_pressed()) { if(is_row0_pressed()) {
read_key = col_idx; // Key 0, 1, 2, or 3 read_key = col_idx;
// Wait for key release
while(is_row0_pressed()) { while(is_row0_pressed()) {
delay_ms(10); delay_ms(10);
} }
@ -128,22 +111,20 @@ int main(void)
} }
} }
// Restore columns
LPC_GPIO2->FIOSET = COL_MASK_P2; LPC_GPIO2->FIOSET = COL_MASK_P2;
LPC_GPIO0->FIOSET = COL_MASK_P0; LPC_GPIO0->FIOSET = COL_MASK_P0;
// Update brightness immediately on key press
if(read_key != 0xFF && read_key != last_key) { if(read_key != 0xFF && read_key != last_key) {
last_key = read_key; last_key = read_key;
switch(read_key) { switch(read_key) {
case 0: duty_cycle = 10; break; // 10% case 0: duty_cycle = 10; break;
case 1: duty_cycle = 25; break; // 25% case 1: duty_cycle = 25; break;
case 2: duty_cycle = 50; break; // 50% case 2: duty_cycle = 50; break;
case 3: duty_cycle = 75; break; // 75% case 3: duty_cycle = 75; break;
} }
} }
delay_ms(50); // Main loop delay delay_ms(50);
} }
} }