LCD 基本動作指令/資料寫入
這邊要先說明一下怎麼透過這些GPIO pin腳來對LCD下達命令或是寫入一個個的8bit(1 byte)資料.
LCD模組一般來說有兩個基本動作--"寫入指令"和"寫入資料"--我們先來看看怎麼寫入指令:
static irqreturn_t cir_irq_handler (int irq, void *dev_id, struct pt_regs *regs) { struct timeval tv; long deltv; int data; struct cir_device_data *dev; dev = (struct cir_device_data *)dev_id; /* get current time */ do_gettimeofday(&tv); if(dev->ir_state == IR_STATE_0) { dev->ir_state = IR_STATE_1; /* Initializate ir variable */ dev->ir_count = 0; dev->complete_bits = 0; /* Configure to generate an interrupt on rising edge * Wait 9ms pre-pulse. */ set_irq_type(gpio_to_irq(CIR_GPIO), IRQT_RISING); } else { deltv = tv.tv_sec - dev->lasttv.tv_sec; /* calc time since last interrupt in microseconds */ data = (int) (deltv*1000000 + tv.tv_usec - dev->lasttv.tv_usec); decode_process(dev, data); } /* restore time */ dev->lasttv = tv; return IRQ_HANDLED; }
static int check_bit(int interval) { int bit = 0; /* if interval is 1.12ms(+-20%) then bit 0 */ if(interval > 896 && interval < 1344) bit = 0; /* if interval is 2.25ms(+-20%) then bit 1 */ else if(interval > 1800 && interval < 2700) bit = 1; else /* invalid data bit */ bit = -1; return bit; } static void decode_process(struct cir_device_data *dev, int interval) { int bitvalue = 0; switch(dev->ir_state){ case IR_STATE_1: /* Configure to generate an interrupt on falling edge * decision 9ms pre-pulse, within a +-20% range of the nominal value * 9000 - (9000*0.2) = 7200, 9000+(9000*0.2) = 9900 */ set_irq_type(gpio_to_irq(CIR_GPIO), IRQT_FALLING); if(interval > 7200 && interval < 10800) dev->ir_state = IR_STATE_2; // pre-pulse detected. else dev->ir_state = IR_STATE_0; // exit with error, return state_0 break; case IR_STATE_2: /* decision long interval(4.5ms) or short interval (2.25ms) * long interval is normal message, short interval is repetition code. * 4500 - (4500*0.2) = 3600, 4500 + (4500*0.2) = 5400 * 2250 - (2250*0.2) = 1800, 2250 + (2250*0.2) = 2700 */ if(interval > 3600 && interval < 5400) { dev->ir_state = IR_STATE_3; } else if(interval > 1800 && interval < 2700) { /* driver not supported repetition. * Return state_0 */ dev->ir_state = IR_STATE_0; //repeat state. } else { dev->ir_state = IR_STATE_0; // exit with error, return state_0 printk(KERN_DEBUG "CIR:exit with error!\n"); } break; case IR_STATE_3: /* 32 bits entire message receiving */ bitvalue = check_bit(interval); if(bitvalue < 0) { /* invalid data bit */ dev->ir_state = IR_STATE_0; } else { dev->complete_bits <<= 1; dev->complete_bits |= bitvalue; dev->ir_state = IR_STATE_3; dev->ir_count++; if(dev->ir_count >= CIR_DATA_BITS) { /* receiving complete */ dev->ir_state = IR_STATE_0; /* store to buffer */ dev->buff[dev->head] = dev->complete_bits; dev->head = (dev->head + 1) % CIR_BUFFER_SIZE; wake_up_interruptible(&dev->waitq); } } break; default: break; } }