diff --git a/ES/Project/code_with_nokia.c b/ES/Project/code_with_nokia.c index 7587ea3..c30660a 100644 --- a/ES/Project/code_with_nokia.c +++ b/ES/Project/code_with_nokia.c @@ -44,7 +44,7 @@ #define OP_CLR 4 #define OP_RES 5 -/* ===== Globals ===== */ +/* ===== Predeclared Variables ===== */ int input_num, stored_num, result; unsigned int operation; unsigned int current_base; @@ -56,9 +56,14 @@ unsigned int key, last_key, stable; unsigned int button_state, last_button_state, button_stable; unsigned long last_mode_press_time; +volatile unsigned long sys_millis; -/* ===== System tick counter ===== */ -volatile unsigned long sys_millis = 0; +unsigned int col, row, row_bits, d, unum, i; +char buf[17]; +volatile unsigned int loop_idx, beep_i; +unsigned int frequency_hz, duration_ms; +unsigned int half_period_us; +unsigned long start_time, end_time, now; /* ===== Nokia Tune Notes ===== */ typedef struct { @@ -67,62 +72,33 @@ typedef struct { } Note; const Note nokia_tune[] = { - /* Main Nokia ringtone sequence - full 2 minute loop */ - {330, 125}, /* E4 */ - {311, 125}, /* D#4 */ - {370, 125}, /* F#4 */ - {415, 250}, /* G#4 */ - {311, 125}, /* D#4 */ - {370, 125}, /* F#4 */ - {415, 500}, /* G#4 */ + /* Complete Nokia Tune - Full sequence */ + {330, 125}, {311, 125}, {370, 125}, {415, 250}, + {311, 125}, {370, 125}, {415, 500}, {0, 100}, - /* Repeat section */ - {330, 125}, /* E4 */ - {311, 125}, /* D#4 */ - {370, 125}, /* F#4 */ - {415, 250}, /* G#4 */ - {311, 125}, /* D#4 */ - {370, 125}, /* F#4 */ - {415, 250}, /* G#4 */ + {330, 125}, {311, 125}, {370, 125}, {415, 250}, + {311, 125}, {370, 125}, {415, 250}, {0, 100}, - {330, 125}, /* E4 */ - {311, 125}, /* D#4 */ - {370, 125}, /* F#4 */ - {415, 250}, /* G#4 */ - {311, 125}, /* D#4 */ - {370, 125}, /* F#4 */ - {415, 250}, /* G#4 */ + {330, 125}, {311, 125}, {370, 125}, {415, 250}, + {311, 125}, {370, 125}, {415, 250}, {0, 100}, - {330, 125}, /* E4 */ - {311, 125}, /* D#4 */ - {370, 125}, /* F#4 */ - {415, 500}, /* G#4 (longer) */ + {330, 125}, {311, 125}, {370, 125}, {415, 500}, + {0, 100}, - /* Extended section - full melody */ - {370, 125}, /* F#4 */ - {415, 125}, /* G#4 */ - {466, 125}, /* A#4 */ - {523, 250}, /* C5 */ - {415, 125}, /* G#4 */ - {466, 125}, /* A#4 */ - {523, 250}, /* C5 */ + {370, 125}, {415, 125}, {466, 125}, {523, 250}, + {415, 125}, {466, 125}, {523, 250}, {0, 100}, - {370, 125}, /* F#4 */ - {415, 125}, /* G#4 */ - {466, 125}, /* A#4 */ - {523, 250}, /* C5 */ - {415, 125}, /* G#4 */ - {466, 125}, /* A#4 */ - {523, 500}, /* C5 (longer) */ + {370, 125}, {415, 125}, {466, 125}, {523, 250}, + {415, 125}, {466, 125}, {523, 250}, {0, 100}, - /* Final variation */ - {330, 125}, /* E4 */ - {311, 125}, /* D#4 */ - {370, 125}, /* F#4 */ - {415, 250}, /* G#4 */ - {311, 125}, /* D#4 */ - {370, 125}, /* F#4 */ - {415, 1000}, /* G#4 (very long) */ + {370, 125}, {415, 125}, {466, 125}, {523, 500}, + {0, 100}, + + {330, 125}, {311, 125}, {370, 125}, {415, 250}, + {311, 125}, {370, 125}, {415, 250}, {0, 100}, + + {330, 125}, {311, 125}, {370, 125}, {415, 250}, + {311, 125}, {370, 125}, {415, 1000}, {0, 0} /* End marker */ }; @@ -150,7 +126,7 @@ unsigned char is_operator_active(unsigned int key); int base_arith(int a, int b, unsigned int op, unsigned int base); unsigned long millis(void); void beeper_init(void); -void play_tone(unsigned int frequency, unsigned int duration); +void play_tone(unsigned int freq, unsigned int dur); void play_nokia_tune(void); /* =================================================== */ @@ -160,7 +136,6 @@ void play_nokia_tune(void); void delay(volatile unsigned int d){ while(d--) __NOP(); } void lcd_delay(unsigned long r){ volatile unsigned long i; for(i=0;iFIOSET = LCD_EN; lcd_delay(100); LPC_GPIO0->FIOCLR = LCD_EN; lcd_delay(250000); } -void lcd_cmd(unsigned char c){ lcd_write_nibble(c>>4,0); lcd_write_nibble(c,0); } -void lcd_data(unsigned char d){ lcd_write_nibble(d>>4,1); lcd_write_nibble(d,1); } + +void lcd_cmd(unsigned char c){ + lcd_write_nibble(c>>4,0); + lcd_write_nibble(c,0); +} + +void lcd_data(unsigned char d){ + lcd_write_nibble(d>>4,1); + lcd_write_nibble(d,1); +} void lcd_init(void){ lcd_delay(5000000); @@ -181,20 +164,23 @@ void lcd_init(void){ lcd_write_nibble(0x03,0); lcd_delay(500000); lcd_write_nibble(0x03,0); lcd_delay(500000); lcd_write_nibble(0x02,0); lcd_delay(500000); - lcd_cmd(0x28); lcd_cmd(0x0C); lcd_cmd(0x01); lcd_delay(500000); lcd_cmd(0x06); + lcd_cmd(0x28); lcd_cmd(0x0C); lcd_cmd(0x01); + lcd_delay(500000); + lcd_cmd(0x06); } -void lcd_print_str(const char *s){ while(*s) lcd_data(*s++); } +void lcd_print_str(const char *s){ + while(*s) lcd_data(*s++); +} void lcd_print_num(int num, unsigned int base){ - char buf[17]; int i=0; unsigned int unum; - + i=0; if(base==MODE_DEC && num<0){ lcd_data('-'); num=-num; } unum=(unsigned int)num; if(unum==0){ lcd_data('0'); return; } while(unum>0 && i<16){ - unsigned int d=unum%base; + d=unum%base; buf[i++]=(d<10)?('0'+d):('A'+d-10); unum/=base; } @@ -209,9 +195,11 @@ void display_mode(void){ else if(current_base==MODE_BASE4) lcd_print_str("BASE4 "); else if(current_base==MODE_OCT) lcd_print_str("OCT "); else if(current_base==MODE_DEC) lcd_print_str("DEC "); - else { lcd_print_str("HEX"); - if(hex_op_mode) lcd_print_str("[OPS]"); - else lcd_print_str(" "); } + else { + lcd_print_str("HEX"); + if(hex_op_mode) lcd_print_str("[OPS]"); + else lcd_print_str(" "); + } } void display_input(void){ @@ -230,14 +218,16 @@ void display_result(void){ /* ---- Keypad scanning ---- */ unsigned int scan_keypad(void){ - unsigned int col,row,row_bits; for(col=0;col<4;col++){ LPC_GPIO0->FIOSET=COL_MASK; delay(50); LPC_GPIO0->FIOCLR=(1<<(COL_BASE+col)); delay(200); row_bits=(LPC_GPIO0->FIOPIN&ROW_MASK)>>ROW_BASE; if(row_bits!=0x0F){ for(row=0;row<4;row++) - if(!(row_bits&(1<FIOSET=COL_MASK; return col*4+row; } + if(!(row_bits&(1<FIOSET=COL_MASK; + return col*4+row; + } } } LPC_GPIO0->FIOSET=COL_MASK; @@ -263,7 +253,7 @@ void change_mode(void){ /* ---- Double-press / mode handler ---- */ void handle_mode_button(void){ - unsigned long now=millis(); + now=millis(); if(button_stable==3 && button_state==1){ if(current_base==MODE_HEX){ if((now-last_mode_press_time)<2000){ @@ -294,19 +284,27 @@ int base_arith(int a,int b,unsigned int op,unsigned int base){ default: r=a; break; } - if(base!=MODE_DEC){ /* wrap-around for others */ + if(base!=MODE_DEC){ if(r<0) r=((r%base)+base)%base; - else r%= (base*base*base*base); /* loose limit */ + else r%= (base*base*base*base); } return r; } /* ---- Operator control ---- */ -void operate(unsigned int op){ stored_num=input_num; input_num=0; operation=op; result_displayed=0; } +void operate(unsigned int op){ + stored_num=input_num; + input_num=0; + operation=op; + result_displayed=0; +} + void perform_operation(void){ result=base_arith(stored_num,input_num,operation,current_base); display_result(); - input_num=result; operation=OP_NONE; result_displayed=1; + input_num=result; + operation=OP_NONE; + result_displayed=1; } unsigned char is_operator_active(unsigned int key){ @@ -323,37 +321,40 @@ void beeper_init(void){ LPC_GPIO0->FIOCLR = BEEPER_PIN; } -void play_tone(unsigned int frequency, unsigned int duration){ - unsigned long start_time = millis(); - unsigned long end_time = start_time + duration; +void play_tone(unsigned int freq, unsigned int dur){ + start_time = millis(); + end_time = start_time + dur; - if(frequency == 0){ + if(freq == 0){ while(millis() < end_time){ - LPC_GPIO0->FIOCLR = BEEPER_PIN; - delay(1000); + __NOP(); } return; } - unsigned int half_period_us = 1000000 / (2 * frequency); + half_period_us = 500000 / freq; while(millis() < end_time){ LPC_GPIO0->FIOSET = BEEPER_PIN; - for(volatile unsigned int i = 0; i < half_period_us; i++) __NOP(); + for(beep_i = 0; beep_i < half_period_us; beep_i++) __NOP(); + LPC_GPIO0->FIOCLR = BEEPER_PIN; - for(volatile unsigned int i = 0; i < half_period_us; i++) __NOP(); + for(beep_i = 0; beep_i < half_period_us; beep_i++) __NOP(); } LPC_GPIO0->FIOCLR = BEEPER_PIN; } void play_nokia_tune(void){ - while(1){ /* INFINITE LOOP - plays forever */ - for(int i = 0; nokia_tune[i].frequency != 0; i++){ - play_tone(nokia_tune[i].frequency, nokia_tune[i].duration); + while(1){ + loop_idx = 0; + while(nokia_tune[loop_idx].frequency != 0){ + frequency_hz = nokia_tune[loop_idx].frequency; + duration_ms = nokia_tune[loop_idx].duration; + play_tone(frequency_hz, duration_ms); + loop_idx++; } - /* Small delay before repeating */ - delay(50000); + delay(100000); } } @@ -363,20 +364,27 @@ void play_nokia_tune(void){ int main(void){ current_base=MODE_DEC; input_num=stored_num=result=0; - operation=OP_NONE; result_displayed=0; - key=last_key=0xFF; stable=0; - button_stable=0; button_state=last_button_state=0; - hex_op_mode=0; last_mode_press_time=0; + operation=OP_NONE; + result_displayed=0; + key=last_key=0xFF; + stable=0; + button_stable=0; + button_state=last_button_state=0; + hex_op_mode=0; + last_mode_press_time=0; + sys_millis=0; SystemCoreClockUpdate(); - SysTick_Config(SystemCoreClock/1000); // 1 ms tick + SysTick_Config(SystemCoreClock/1000); /* GPIO mux: make pins GPIO */ - LPC_PINCON->PINSEL0=0; LPC_PINCON->PINSEL1=0; - LPC_PINCON->PINSEL3=0; LPC_PINCON->PINSEL4=0; - LPC_PINCON->PINSEL0 &= ~0xFFF00000; // P0.4–P0.11 as GPIO + LPC_PINCON->PINSEL0=0; + LPC_PINCON->PINSEL1=0; + LPC_PINCON->PINSEL3=0; + LPC_PINCON->PINSEL4=0; + LPC_PINCON->PINSEL0 &= ~0xFFF00000; - /* Directions: keypad columns out, rows in; LCD pins out; MODE button in; beeper out */ + /* Directions */ LPC_GPIO0->FIODIR |= COL_MASK | LCD_DATA_MASK | LCD_RS | LCD_EN | BEEPER_PIN; LPC_GPIO0->FIODIR &= ~ROW_MASK; LPC_GPIO0->FIOSET = COL_MASK; @@ -388,41 +396,8 @@ int main(void){ display_mode(); display_input(); - /* Play Nokia tune on loop in background */ play_nokia_tune(); - /* This line never executes because play_nokia_tune() loops forever */ - while(1){ - key=scan_keypad(); - button_state=scan_mode_button(); - - if(key==last_key) stable=(stable<5)?stable+1:stable; - else{ last_key=key; stable=0; } - - if(button_state==last_button_state) - button_stable=(button_stable<5)?button_stable+1:button_stable; - else{ last_button_state=button_state; button_stable=0; } - - handle_mode_button(); - - if(stable==3 && key!=0xFF){ - if(is_operator_active(key)){ - switch(key){ - case 11: operate(OP_ADD); display_input(); break; - case 12: input_num=stored_num=result=0; - operation=OP_NONE; display_input(); break; - case 13: operate(OP_SUB); display_input(); break; - case 14: operate(OP_MUL); display_input(); break; - case 15: perform_operation(); break; - } - } else if(is_valid_digit(key)){ - result_displayed=0; - input_num=input_num*current_base+key; - display_input(); - } - stable=5; - } - - delay(3000); - } + while(1); + return 0; }