/******************************************************* ** nokia 3310 LCD scope ** THIS IS IT!!! :-) june 1 , 2009 *** B0 - uS/Div switch* B1 - Y pos* B2 - sw soft GAIN* B4 - spst sw HOLD function /hold MODE open sw* B5 - trigger LVL button / 5 & 128 WHATS NEW/UPGRADED: =================== shows a PROPER square wave has switchable GAIN FS=5V and FS=2.6V has also TRIGGER/hold function by: master Regulus Berdin A.K.A zer0w1ng much accurate; Tosc = 32 @ 20MHz bus clock 100ms 50mS 20mS 10mS 2mS 500uS us/Div -ADD trigger TOGGLE function (done!) -ADD better HOLD function (done!) -ADD toggle function to softGAIN (done!)*****************************************************Changes:-long press */#include <18F452.h>#device adc=8#use delay(clock=20M)//#FUSES NOWDT,NOPROTECT,NOOSCSEN,BROWNOUT,BORV20,STVREN,NODEBUG,NOWRT,NOWRTD,NOWRTB//#FUSES NOWRTC,NOCPD,NOCPB,NOEBTR,NOEBTRB#FUSES NOWDT, HS, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG#use fast_io(b)#define LCD_SCLK 4#define LCD_SDA 2 #define LCD_DC 3#define LCD_CS 1#define LCD_RES 0#byte lcdport = 0xF83 #byte lcdport_tris = 0xF95 #bit nok_sclk = lcdport.LCD_SCLK //pin2 LCD port_D4 #bit nok_sda = lcdport.LCD_SDA //pin3 LCD port_D2 #bit nok_dc = lcdport.LCD_DC //pin4 LCD port_D3 #bit nok_cs = lcdport.LCD_CS //pin5 LCD port_D1 #bit nok_res = lcdport.LCD_RES //pin8 LCD port_D0 //============================================================//#include <2465.C>#include "3310.c"#define speaker pin_C7#define TIMEOUT 1000#define DEFAULT_TRIGGER_DELAY 1#define BTN_MASK (1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<1 | 1)#define DEBOUNCE_MS 30#define MINIMUM_ADC_TIME 15#define TRIGGER_LED_PORT PIN_D7/* 100ms, 50ms, 20ms, 10ms, 2ms, 500uS */#define INTERVAL_COUNT 6#define INTERVAL_DEFAULT 2#define INTERVAL_STR_SIZE 6#define SCALE_COUNT 4#define SCALE_DEFAULT 0#define SCALE_STR_SIZE 6#define TRIGGER_DEFAULT 16unsigned char samples[84];unsigned int8 i;unsigned int scale;unsigned int8 trigger_level = TRIGGER_DEFAULT;signed int8 position = 0;unsigned int8 interval = INTERVAL_DEFAULT;unsigned int8 scale_index = SCALE_DEFAULT;unsigned int8 scale_dc_level = (128 >> (3-SCALE_DEFAULT));unsigned int16 timer_value;unsigned int8 timer_divider;typedef struct { unsigned int16 value; char *str;} val_str_t;const unsigned int16 const interval_delay[INTERVAL_COUNT] = { 1000, 500, 200, 100, 20, 5};const unsigned int8 const scale_value[SCALE_COUNT] = {8,4,2,1};void view_settings();void beep();void plot_samples(void);signed int8 compute_y(unsigned int8 v);void scope_settings(){ delay_ms(50); //switch debounce nokia_clean_ddram(); view_settings();}//------------------------void show_scale(void){ nokia_gotoxy(25,5); switch (scale) { case 8: printf(nokia_printchar, " 5V "); break; case 4: printf(nokia_printchar, " 2V5"); break; case 2: printf(nokia_printchar, "1V25"); break; case 1: printf(nokia_printchar, "V625"); break; }}void show_interval(void){ unsigned int8 interv; interv = interval_delay[interval]/10; nokia_gotoxy(53,5); if (interv) printf(nokia_printchar, "%3ums", interv); else printf(nokia_printchar, "500us");}void erase_trigger(void){ nokia_gotoxy(0, (trigger_level/8)); nokia_write_data(0x00); nokia_gotoxy(1, (trigger_level/8)); nokia_write_data(0x00); nokia_gotoxy(0,5); printf(nokia_printchar," ");}void show_trigger(void){ LcdPixel(0, trigger_level); LcdPixel(1, trigger_level); nokia_gotoxy(0,5); printf(nokia_printchar,"t%u", 31-trigger_level);}void clear_status_line(void){ nokia_gotoxy(0,5); printf(nokia_printchar," ");}void view_settings() { clear_status_line(); show_interval(); show_scale(); show_trigger();}enum { STATE_FIND_LOW, STATE_FIND_TRIGGER, STATE_COUNTING_LOW, STATE_COUNTING_HIGH, STATE_DUMMY};void show_frequency(){ unsigned int16 cnt; unsigned int8 i, state; float d, intv; signed int8 y, tr; state = STATE_COUNTING_LOW; cnt = 0; tr = compute_y(samples[0]); for (i=0;i<84;++i) { y = compute_y(samples[i]); switch (state) { case STATE_COUNTING_LOW: ++cnt; if (y>tr) state = STATE_COUNTING_HIGH; break; case STATE_COUNTING_HIGH: ++cnt; if (y<=tr) i=100; break; } } #if 0 printf(nokia_printchar,"%Lu :%Lu %Lu", cnt, timer_value,timer_divider);#else //timer_divider if (i>=100) { d = timer_value/84.0; intv = cnt; intv *= timer_divider; printf(nokia_printchar,"Freq:%2.3gkHz", 5000.0/(intv * d)); } else { printf(nokia_printchar,"Freq: invalid"); }#endif}//===================================================================signed int8 compute_y(unsigned int8 v){#if 1 return position + 15 - ((v >> (3-scale_index)) - scale_dc_level) ;#else v >>= (3-scale_index); return position + 31 - v;#endif }unsigned char debounce_pin(unsigned char bmask){ if ((input_b() & bmask)) return 0; delay_ms(DEBOUNCE_MS); if ((input_b() & bmask)) return 0; return 1;}unsigned int8 wait_for_release(void){ if ((input_b() & BTN_MASK) != BTN_MASK) return 1; delay_ms(DEBOUNCE_MS); if ((input_b() & BTN_MASK) != BTN_MASK) return 1; return 0;}void adjust_trigger(void){ erase_trigger(); if (trigger_level>1) --trigger_level; else trigger_level = 30; show_trigger();}void adjust_position(void){ --position; if (position<-40) position = 40; plot_samples(); nokia_gotoxy(60,5); printf(nokia_printchar," "); nokia_gotoxy(60,5); printf(nokia_printchar,"%d", -position); }void adjust_interval(void){ ++interval; if (interval>=INTERVAL_COUNT) interval = 0; show_interval();}void check_buttons(void){ unsigned int8 tmr; //check for any buttons pressed if ((input_b() & BTN_MASK) == BTN_MASK) return; //position if (debounce_pin(1<<1)) { nokia_gotoxy(0,5); printf(nokia_printchar,"Position: "); adjust_position(); tmr = 34; /* 500ms long press*/ while(wait_for_release()) { delay_ms(15); if (tmr) --tmr; else adjust_position(); } view_settings(); } //trigger level if (debounce_pin(1<<5)) { adjust_trigger(); tmr = 10; /* 500ms long press*/ while(wait_for_release()) { delay_ms(50); if (tmr) --tmr; else adjust_trigger(); } } //Gain/scale if (debounce_pin(1<<2)) { ++scale_index; if (scale_index >= SCALE_COUNT) scale_index = 0; scale = scale_value[scale_index]; scale_dc_level = (128 >> (3-scale_index)); show_scale(); while(wait_for_release()) continue; } //Hold if (debounce_pin(1<<4)) { nokia_gotoxy(0,5); printf(nokia_printchar,"H "); while(wait_for_release()) continue; view_settings(); } //interval if (debounce_pin(1)) { adjust_interval(); while(wait_for_release()) continue; } //freq if (debounce_pin(1<<3)) { clear_status_line(); nokia_gotoxy(0,5); show_frequency(); while(wait_for_release()) continue; view_settings(); } }void trigger(void){ unsigned int16 timeout1, timeout2; output_high(TRIGGER_LED_PORT); //wait until reading gets below mid timeout1 = TIMEOUT; do { check_buttons(); read_adc(adc_start_only); delay_us(MINIMUM_ADC_TIME + 30); if (compute_y(read_adc(adc_read_only))>=trigger_level) break; } while (--timeout1); //wait until reading gets above mid timeout2 = TIMEOUT; do { check_buttons(); read_adc(adc_start_only); delay_us(MINIMUM_ADC_TIME + 30); if (compute_y(read_adc(adc_read_only))<trigger_level) break; } while (--timeout2); nokia_gotoxy(0,5); if (timeout1 == 0 || timeout2 == 0) { output_low(TRIGGER_LED_PORT); } else { }}#define PLOT_START 3#define PLOT_END 83void plot_samples(void){ signed int8 y1, y2, yz; unsigned int8 x; //6 x 84 erase_column(PLOT_START); yz = compute_y(samples[0]); for(x=PLOT_START+1; x<=PLOT_END; x++) { y1 = yz; yz = y2 = compute_y(samples[x-PLOT_START]); erase_column(x); if ( (y1<0 && y2<0) || (y1>31 && y2>31) /* || (y1>31 && y2<0) || (y2>31 && y1<0) */ ) continue; if (y1>31) y1 = 31; if (y2>31) y2 = 31; if (y1<0) y1 = 0; if (y2<0) y2 = 0; lcd_fast_vertical_line(x,y1,y2); }}void get_samples(void){ unsigned int8 i; unsigned int16 pinterval; pinterval = interval_delay[interval]; if (pinterval<MINIMUM_ADC_TIME) pinterval = MINIMUM_ADC_TIME; // 0 1 2 3 4 5 //1000, 500, 200, 100, 20, 5 switch(interval) { case 0: setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 ); timer_divider = 8; break; case 1: setup_timer_1( T1_INTERNAL | T1_DIV_BY_4 ); timer_divider = 4; break; case 2: setup_timer_1( T1_INTERNAL | T1_DIV_BY_2 ); timer_divider = 2; break; default: setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 ); timer_divider = 1; } set_timer1(0); for (i=0;i<84;++i) { read_adc(adc_start_only); delay_us(pinterval); samples[i]=read_adc(adc_read_only); /* delay_us(2); */ } timer_value = get_timer1();}void main(){ lcdport_tris = 0x00; port_b_pullups (true); set_tris_b(BTN_MASK); nokia_init(); interval = INTERVAL_DEFAULT; //initial value 20mS scope settings scale = scale_value[scale_index]; setup_adc_ports(AN0_AN1_AN3); setup_adc(ADC_CLOCK_DIV_32); set_adc_channel(0); delay_us(10); nokia_gotoxy(1,1); printf(nokia_printchar," Elab.Ph "); nokia_gotoxy(1,2); printf(nokia_printchar," 3310 scope! "); nokia_gotoxy(1,5); printf(nokia_printchar," Version 1.5 "); delay_ms(1000); nokia_clean_ddram(); view_settings(); delay_ms(100); while(true) { trigger(); get_samples(); plot_samples(); }}
/////////////////////////////////////////////////////////////////////////////////* LPH7779-LCD(Nokia 3310) library*/////////////////////////////////////////////////////////////////////////////////char CONST TABLE5 [240] = { // ASCII table for NOKIA LCD: 96 rows * 5 bytes= 480 bytes 0x00,0x00,0x00,0x00,0x00, // 20 space 0x00,0x00,0x5f,0x00,0x00, // 21 ! 0x00,0x07,0x00,0x07,0x00, // 22 " 0x14,0x7f,0x14,0x7f,0x14, // 23 # 0x24,0x2a,0x7f,0x2a,0x12, // 24 $ 0x23,0x13,0x08,0x64,0x62, // 25 % 0x36,0x49,0x55,0x22,0x50, // 26 & 0x00,0x05,0x03,0x00,0x00, // 27 ' 0x00,0x1c,0x22,0x41,0x00, // 28 ( 0x00,0x41,0x22,0x1c,0x00, // 29 ) 0x14,0x08,0x3e,0x08,0x14, // 2a * 0x08,0x08,0x3e,0x08,0x08, // 2b + 0x00,0x50,0x30,0x00,0x00, // 2c , 0x08,0x08,0x08,0x08,0x08, // 2d - 0x00,0x60,0x60,0x00,0x00, // 2e . 0x20,0x10,0x08,0x04,0x02, // 2f / 0x3e,0x51,0x49,0x45,0x3e, // 30 0 0x00,0x42,0x7f,0x40,0x00, // 31 1 0x42,0x61,0x51,0x49,0x46, // 32 2 0x21,0x41,0x45,0x4b,0x31, // 33 3 0x18,0x14,0x12,0x7f,0x10, // 34 4 0x27,0x45,0x45,0x45,0x39, // 35 5 0x3c,0x4a,0x49,0x49,0x30, // 36 6 0x01,0x71,0x09,0x05,0x03, // 37 7 0x36,0x49,0x49,0x49,0x36, // 38 8 0x06,0x49,0x49,0x29,0x1e, // 39 9 0x00,0x36,0x36,0x00,0x00, // 3a : 0x00,0x56,0x36,0x00,0x00, // 3b ; 0x08,0x14,0x22,0x41,0x00, // 3c < 0x14,0x14,0x14,0x14,0x14, // 3d = 0x00,0x41,0x22,0x14,0x08, // 3e > 0x02,0x01,0x51,0x09,0x06, // 3f ? 0x32,0x49,0x79,0x41,0x3e, // 40 @ 0x7e,0x11,0x11,0x11,0x7e, // 41 A 0x7f,0x49,0x49,0x49,0x36, // 42 B 0x3e,0x41,0x41,0x41,0x22, // 43 C 0x7f,0x41,0x41,0x22,0x1c, // 44 D 0x7f,0x49,0x49,0x49,0x41, // 45 E 0x7f,0x09,0x09,0x09,0x01, // 46 F 0x3e,0x41,0x49,0x49,0x7a, // 47 G 0x7f,0x08,0x08,0x08,0x7f, // 48 H 0x00,0x41,0x7f,0x41,0x00, // 49 I 0x20,0x40,0x41,0x3f,0x01, // 4a J 0x7f,0x08,0x14,0x22,0x41, // 4b K 0x7f,0x40,0x40,0x40,0x40, // 4c L 0x7f,0x02,0x0c,0x02,0x7f, // 4d M 0x7f,0x04,0x08,0x10,0x7f, // 4e N 0x3e,0x41,0x41,0x41,0x3e}; // 4f Ochar CONST TABLE6 [240] = { 0x7f,0x09,0x09,0x09,0x06, // 50 P 0x3e,0x41,0x51,0x21,0x5e, // 51 Q 0x7f,0x09,0x19,0x29,0x46, // 52 R 0x46,0x49,0x49,0x49,0x31, // 53 S 0x01,0x01,0x7f,0x01,0x01, // 54 T 0x3f,0x40,0x40,0x40,0x3f, // 55 U 0x1f,0x20,0x40,0x20,0x1f, // 56 V 0x3f,0x40,0x38,0x40,0x3f, // 57 W 0x63,0x14,0x08,0x14,0x63, // 58 X 0x07,0x08,0x70,0x08,0x07, // 59 Y 0x61,0x51,0x49,0x45,0x43, // 5a Z 0x00,0x7f,0x41,0x41,0x00, // 5b [ 0x02,0x04,0x08,0x10,0x20, // 5c \ 0x00,0x41,0x41,0x7f,0x00, // 5d ñ 0x04,0x02,0x01,0x02,0x04, // 5e ^ 0x40,0x40,0x40,0x40,0x40, // 5f _ 0x00,0x01,0x02,0x04,0x00, // 60 ` 0x20,0x54,0x54,0x54,0x78, // 61 a 0x7f,0x48,0x44,0x44,0x38, // 62 b 0x38,0x44,0x44,0x44,0x20, // 63 c 0x38,0x44,0x44,0x48,0x7f, // 64 d 0x38,0x54,0x54,0x54,0x18, // 65 e 0x08,0x7e,0x09,0x01,0x02, // 66 f 0x0c,0x52,0x52,0x52,0x3e, // 67 g 0x7f,0x08,0x04,0x04,0x78, // 68 h 0x00,0x44,0x7d,0x40,0x00, // 69 i 0x20,0x40,0x44,0x3d,0x00, // 6a j 0x7f,0x10,0x28,0x44,0x00, // 6b k 0x00,0x41,0x7f,0x40,0x00, // 6c l 0x7c,0x04,0x18,0x04,0x78, // 6d m 0x7c,0x08,0x04,0x04,0x78, // 6e n 0x38,0x44,0x44,0x44,0x38, // 6f o 0x7c,0x14,0x14,0x14,0x08, // 70 p 0x08,0x14,0x14,0x18,0x7c, // 71 q 0x7c,0x08,0x04,0x04,0x08, // 72 r 0x48,0x54,0x54,0x54,0x20, // 73 s 0x04,0x3f,0x44,0x40,0x20, // 74 t 0x3c,0x40,0x40,0x20,0x7c, // 75 u 0x1c,0x20,0x40,0x20,0x1c, // 76 v 0x3c,0x40,0x30,0x40,0x3c, // 77 w 0x44,0x28,0x10,0x28,0x44, // 78 x 0x0c,0x50,0x50,0x50,0x3c, // 79 y 0x44,0x64,0x54,0x4c,0x44, // 7a z 0x00,0x08,0x36,0x41,0x00, // 7b { 0x00,0x00,0x7f,0x00,0x00, // 7c | 0x00,0x41,0x36,0x08,0x00, // 7d } 0x10,0x08,0x08,0x10,0x08, // 7e ~ 0x78,0x46,0x41,0x46,0x78}; // 7f ¦ // 7e,43,40,43,7e --> Ü // 7e,43,42,43,7e --> Ö // 1e,21,21,71,21 --> Ç // 3c,42,53,53,72 --> Ð//function prototypesvoid nokia_init();void nokia_write_command(char bytefornokia_command);void nokia_write_data(char bytefornokia_data);void nokia_write_dorc(char bytefornokia);void nokia_gotoxy(char xnokia, char ynokia);void nokia_contrast (byte contrast);void nokia_printchar(char cvar);void nokia_clean_ddram();void table_to_nokialcd();void LcdPixel (char x, char y);void erase_column(char x); //yuschar char_row,charsel,charpos,chardata;int16 ddram;void nokia_init() { nok_dc=1; // bytes are stored in the display data ram, address counter, incremented automatically delay_us(1); nok_cs=1; // chip disabled delay_us(200); nok_res=0; delay_ms(10); nok_res=1; nokia_write_command(0x21); // set extins extended instruction set nokia_write_command(0xc8); // Vop v1: 0xc8 (for 3V), v2: 0xa0 (for 3V) nokia_write_command(0x13); // bias nokia_write_command(0x20); // horizontal mode from left to right, X axe are incremented automatically, // 0x22 for vertical addressing, back on normal instruction set too nokia_write_command(0x09); // all on delay_ms(50); nokia_clean_ddram(); // reset DDRAM, otherwise the lcd is blurred with random pixels delay_ms(10); nokia_write_command(0x08); // mod control blank change (all off) delay_ms(10); nokia_write_command(0x0c); // mod control normal change}void nokia_clean_ddram() { nokia_gotoxy(0,0); // 84*6=504 clear LCD for (ddram=504; ddram>0; ddram--) nokia_write_data(0x00);}void nokia_write_command(char bytefornokia_command){ nok_dc=0; // byte is a command it is read with the eight SCLK pulse nok_cs=0; // chip enabled nokia_write_dorc(bytefornokia_command); nok_cs=1; // chip disabled}void nokia_write_data(char bytefornokia_data){ nok_dc=1; nok_cs=0; // chip enabled nokia_write_dorc(bytefornokia_data); nok_cs=1; // chip disabled}#define pulse_bit(c, mask) \ nok_sclk=0; \ delay_cycles(1); \ nok_sda=0; \ if (c & mask) \ nok_sda=1; \ delay_us(1); \ nok_sclk=1; \ delay_us(1)// serial write data or command subroutinevoid nokia_write_dorc(char bytefornokia) { pulse_bit(bytefornokia, (1<<7)); pulse_bit(bytefornokia, (1<<6)); pulse_bit(bytefornokia, (1<<5)); pulse_bit(bytefornokia, (1<<4)); pulse_bit(bytefornokia, (1<<3)); pulse_bit(bytefornokia, (1<<2)); pulse_bit(bytefornokia, (1<<1)); pulse_bit(bytefornokia, (1));}void nokia_gotoxy(char xnokia, char ynokia) { // Nokia LCD 3310 Position cursor nokia_write_command(0x40|(ynokia&0x07)); // Y axe initialisation: 0100 0yyy nokia_write_command(0x80|(xnokia&0x7f)); // X axe initialisation: 1xxx xxxx}void nokia_contrast (char contrast) { nokia_write_command(0x21); // LCD Extended Commands. nokia_write_command(0x80 | contrast); // Set LCD Vop (Contrast). nokia_write_command(0x20); // LCD Standard Commands, horizontal addressing mode.}void nokia_printchar(char cvar) { // Write 1 character to LCD charsel=cvar; table_to_nokialcd();}void table_to_nokialcd() { // extract ascii from tables & write to LCD if (charsel<0x20) return; if (charsel>0x7f) return; for (char_row=0;char_row<5;char_row++) { if (charsel<0x50){charpos=(((charsel&0xff)-0x20)*5);chardata=TABLE5[(charpos+char_row)];} // use TABLE5 if (charsel>0x4f){charpos=(((charsel&0xff)-0x50)*5);chardata=TABLE6[(charpos+char_row)];} // use TABLE6 nokia_write_data(chardata); // send data to nokia } nokia_write_data(0x00); // 1 byte (always blank)}/*void LcdPixel (char x, char y){ int16 offset; byte data; if (x > 84) return; if (y > 48) return; offset = y - ((y / 8) * 8) - 1; data = (0x01 << offset); nokia_gotoxy(x, (y/6)); nokia_write_data(data);}*/void LcdPixel (char x, char y) //yus { char offset; byte data; if (x > 84) return; if (y > 48) return; offset = y % 8; data = (0x01<<offset); nokia_gotoxy(x, (y/8)); nokia_write_data(data);} void erase_column(char x) //yus{ char line; for(line=0; line<4; line++) //for(line=0; line<6; line++) { nokia_gotoxy(x, line); //x nokia_write_data(0x00); }}void lcd_vertical_line (char x, char y1, char y2) //yusnew { char i, temp, line1, line2, data; if( (x>83) || (y1>47) || (y2>47) ) return; //exit if out of range if(y1>y2) { temp = y1; y1 = y2; //swap variables y2 = temp; } line1 = y1>>3; //divide by 8 line2 = y2>>3; for(i=line1; i<=line2; i++) { data = 0xff; nokia_gotoxy(x,i); if(i==line1) { data = 0; temp = 8 - (y1 % 8); while(temp--) data |= (0x80>>temp); } if(i==line2) { temp = 7 - (y2 % 8); while(temp--) data &= ~(0x80>>temp); } nokia_write_data(data); }}const unsigned char pow2[] = {1, 2, 4, 8, 16, 32, 64, 128};void lcd_fast_vertical_line (char px, char py1, char py2) { unsigned char cline, ctr, data, p2, y1, y2, x; if( (px>83) || (py1>47) || (py2>47) ) return; //exit if out of range x = px; if(py1>py2) { y1 = py2; y2 = py1; } else { y2 = py2; y1 = py1; } ctr = y1 & 7; cline = y1 >> 3; data = 0; p2 = pow2[ctr]; x |= 0x80; cline |= 0x40; while (y1<=y2) { data |= p2; if (ctr>=7) { nok_dc=0; delay_cycles(1); nok_cs=0; nokia_write_dorc(x); nok_cs=1; delay_cycles(1); nok_dc=0; delay_cycles(1); nok_cs=0; nokia_write_dorc(cline); nok_cs=1; delay_cycles(1); nok_dc=1; delay_cycles(1); nok_cs=0; nokia_write_dorc(data); nok_cs=1; data = 0; ++cline; ctr = 0; p2 = 1; } else { ++ctr; p2 <<= 1; } ++y1; } if (ctr) { nok_dc=0; delay_cycles(1); nok_cs=0; nokia_write_dorc(x); nok_cs=1; delay_cycles(1); nok_dc=0; delay_cycles(1); nok_cs=0; nokia_write_dorc(cline); nok_cs=1; delay_cycles(1); nok_dc=1; delay_cycles(1); nok_cs=0; nokia_write_dorc(data); nok_cs=1; }}
magkanu nagastus mo jan sirpara makapaghanda ako