This commit is contained in:
sherlock 2025-10-23 12:53:16 +05:30
parent d783943935
commit 023708f6d0

View file

@ -4,32 +4,31 @@
unsigned long int duty_cycle = 0;
unsigned long int pwm_counter = 0;
// Pin definitions based on connectors
#define LED_SHIFT 4 // CNA: P0.4-P0.11 (8 LEDs)
// Pin definitions
#define LED_SHIFT 4 // CNA: P0.4-P0.11
#define LED_MASK (0xFF << LED_SHIFT)
// Keypad on CND - Only ROW-0
// Keypad on CND - ROW-0
#define COL0 (1<<0) // P2.0
#define COL1 (1<<1) // P2.1
#define COL2 (1<<23) // P0.23
#define COL3 (1<<24) // P0.24
#define ROW0 (1<<25) // P0.25 (ROW-0 only)
#define ROW0 (1<<25) // P0.25
#define COL_MASK_P0 (COL2 | COL3)
#define COL_MASK_P2 (COL0 | COL1)
#define PWM_PERIOD 100 // Smaller for faster PWM
static void short_delay(volatile unsigned int d) {
while(d--) __NOP();
}
// Set a specific column low, others high
static void set_column(unsigned int col)
{
// Set all columns high first
LPC_GPIO2->FIOSET = COL_MASK_P2;
LPC_GPIO0->FIOSET = COL_MASK_P0;
// Pull specific column low
switch(col) {
case 0: LPC_GPIO2->FIOCLR = COL0; break;
case 1: LPC_GPIO2->FIOCLR = COL1; break;
@ -38,25 +37,25 @@ static void set_column(unsigned int col)
}
}
// Check if ROW-0 is pressed
static unsigned int is_row0_pressed(void)
{
return !(LPC_GPIO0->FIOPIN & ROW0);
}
// PWM Interrupt Handler
// PWM Interrupt Handler - Software PWM
void PWM1_IRQHandler(void)
{
if (LPC_PWM1->IR & (1 << 0))
{
// Software PWM for LEDs (CNA: P0.4-P0.11)
pwm_counter++;
if(pwm_counter >= 3000) pwm_counter = 0;
// Software PWM for all 8 LEDs
if(pwm_counter < duty_cycle)
LPC_GPIO0->FIOSET = LED_MASK; // LEDs ON
LPC_GPIO0->FIOSET = LED_MASK; // All LEDs ON
else
LPC_GPIO0->FIOCLR = LED_MASK; // LEDs OFF
LPC_GPIO0->FIOCLR = LED_MASK; // All LEDs OFF
pwm_counter++;
if(pwm_counter >= PWM_PERIOD)
pwm_counter = 0;
LPC_PWM1->IR = (1 << 0); // Clear interrupt
}
@ -69,90 +68,93 @@ int main(void)
unsigned int stable = 0;
unsigned int last_key = 0xFF;
// === SYSTEM CLOCK SETUP (Optional but recommended) ===
SystemInit(); // Use default clock setup
// === PIN CONFIGURATION ===
LPC_PINCON->PINSEL0 = 0x00000000; // All GPIO
LPC_PINCON->PINSEL1 = 0x00000000;
LPC_PINCON->PINSEL3 = (2 << 14); // PWM1.4 on P1.23 (optional)
LPC_PINCON->PINSEL4 = 0x00000000;
LPC_PINCON->PINSEL0 &= ~(0xFFFF << 8); // Clear P0.4-P0.11 (GPIO)
LPC_PINCON->PINSEL1 &= ~(0xFFFF << 14); // Clear P0.23-P0.28
LPC_PINCON->PINSEL3 &= ~(0x3 << 14); // Clear P1.23
LPC_PINCON->PINSEL4 &= ~(0xF << 0); // Clear P2.0-P2.1
// === GPIO DIRECTION SETUP ===
// CNA: LEDs (P0.4-P0.11)
LPC_GPIO0->FIODIR |= LED_MASK;
// CND: Keypad - Columns output, Row-0 input
LPC_GPIO0->FIODIR |= COL_MASK_P0; // Columns (output)
LPC_GPIO2->FIODIR |= COL_MASK_P2; // Columns (output)
LPC_GPIO0->FIODIR |= LED_MASK; // P0.4-P0.11: LEDs (output)
LPC_GPIO0->FIODIR |= COL_MASK_P0; // Keypad columns (output)
LPC_GPIO2->FIODIR |= COL_MASK_P2; // Keypad columns (output)
LPC_GPIO0->FIODIR &= ~ROW0; // Row-0 (input)
// === INITIALIZE GPIO STATES ===
LPC_GPIO0->FIOCLR = LED_MASK; // LEDs off
LPC_GPIO2->FIOSET = COL_MASK_P2; // Columns high (idle)
LPC_GPIO0->FIOSET = COL_MASK_P0; // Columns high (idle)
// === INITIALIZE GPIO ===
LPC_GPIO0->FIOCLR = LED_MASK; // All LEDs off initially
LPC_GPIO2->FIOSET = COL_MASK_P2; // Columns high
LPC_GPIO0->FIOSET = COL_MASK_P0; // Columns high
// === PWM CONFIGURATION ===
LPC_SC->PCONP |= (1 << 6); // Power on PWM1
LPC_PWM1->TCR = (1 << 1); // Reset PWM
LPC_PWM1->CTCR = 0; // Timer mode
LPC_PWM1->PR = 0; // No prescaler
LPC_PWM1->PR = 99; // Prescaler: divide by 100
// Creates ~10kHz interrupt rate
LPC_PWM1->MR0 = 3000; // PWM period = 3000
LPC_PWM1->MR4 = duty_cycle; // Initial duty cycle = 0
LPC_PWM1->MR0 = PWM_PERIOD; // PWM period = 100
LPC_PWM1->MR4 = 0; // Duty cycle = 0
LPC_PWM1->MCR = (1 << 1) | (1 << 0); // Reset and interrupt on MR0
LPC_PWM1->PCR = (1 << 12); // Enable PWM4 output
LPC_PWM1->LER = (1 << 0) | (1 << 4); // Latch MR0 and MR4
LPC_PWM1->MCR = (1 << 1) | (1 << 0); // Reset on MR0, interrupt enabled
LPC_PWM1->LER = (1 << 0); // Latch MR0
NVIC_EnableIRQ(PWM1_IRQn); // Enable PWM interrupt
NVIC_SetPriority(PWM1_IRQn, 0); // Highest priority
LPC_PWM1->TCR = (1 << 0) | (1 << 3); // Enable counter and PWM
LPC_PWM1->TCR = (1 << 0) | (1 << 3); // Enable PWM and counter
// Initial duty cycle: 10%
duty_cycle = 10;
// === MAIN LOOP ===
while(1)
{
unsigned int read_key = 0xFF;
// Scan ROW-0 only (columns 0-3 = keys 0, 1, 2, 3)
// Scan ROW-0 (keys 0, 1, 2, 3)
for(col_idx = 0; col_idx < 4; col_idx++)
{
set_column(col_idx);
short_delay(200);
short_delay(500);
if(is_row0_pressed()) {
read_key = col_idx; // Key 0, 1, 2, or 3
read_key = col_idx;
break;
}
}
// Restore all columns high
// Restore columns
LPC_GPIO2->FIOSET = COL_MASK_P2;
LPC_GPIO0->FIOSET = COL_MASK_P0;
// Debounce logic
// Debounce
if(read_key == candidate_key) {
if(stable < 3) stable++;
if(stable < 5) stable++;
} else {
candidate_key = read_key;
stable = 1;
}
// Update intensity when key is stable and changed
if(stable >= 3) {
// Update intensity when stable
if(stable >= 5) {
if(candidate_key != last_key && candidate_key != 0xFF) {
last_key = candidate_key;
// Set duty cycle based on key pressed
// Set duty cycle (out of 100)
switch(candidate_key) {
case 0: duty_cycle = 300; break; // 10% of 3000
case 1: duty_cycle = 750; break; // 25% of 3000
case 2: duty_cycle = 1500; break; // 50% of 3000
case 3: duty_cycle = 2250; break; // 75% of 3000
case 0: duty_cycle = 10; break; // 10%
case 1: duty_cycle = 25; break; // 25%
case 2: duty_cycle = 50; break; // 50%
case 3: duty_cycle = 75; break; // 75%
}
LPC_PWM1->MR4 = duty_cycle;
LPC_PWM1->LER = (1 << 4);
}
stable = 3;
stable = 5;
}
short_delay(2000);
short_delay(5000);
}
}