📄 u110.c
字号:
else { //字车反向走动 __prn_pmotor_irq_mask(); ENCODE_STATUS(PRN_PRINTING, MOTOR_STAT_WORKRUSH, NCMOTOR); __prn_cmotor_irq_unmask(); } break; case PRN_PAPERFETCH1: ENCODE_STATUS(PRN_RST0, 0, 0); wake_up(&prn_wait_queue); __prn_irq_mask(); break; default: if ((PRN_STATUS() == PRN_PAPERFETCH2) && (pmotor_direction == 0) && !(__prn_paper_end())) pmotor_direction = 1; if (__prn_paper_end()) ENCODE_STATUS(PRN_PAPERFETCH1, MOTOR_STAT_ACC, NPMOTOR); else { ENCODE_STATUS(PRN_STANDBY, 0, 0); wake_up(&prn_wait_queue); __prn_irq_mask(); } break; }}/******************************************************************* ** ** *******************************************************************/static int arca_prn_reset(void){ unsigned long x; int r; __save_and_cli(x); cmotor_direction = 0; pmotor_direction = 1; cstep_coil = 0; cstep_const = 0; cstep_acc = 0; cstep_dec = 0; pstep_const = 0; pstep_acc = 0; pstep_dec = 0; r = arca_prn_home_position(); __restore_flags(x); return r;}/******************************************************************* ** **黑标定位 给纸电机应该先启动再加速??? *******************************************************************/static int arca_prn_blackmark(void){ bm_timeout = 0; ENCODE_STATUS(PRN_BLACKMARK, MOTOR_STAT_ACC, NPMOTOR); __prn_pmotor_irq_unmask(); return 0;}/******************************************************************* ** ** *******************************************************************/static int arca_prn_newline(void){ ENCODE_STATUS(PRN_NEWLINE, MOTOR_STAT_ACC, NPMOTOR); __prn_pmotor_irq_unmask(); return 0;}/******************************************************************* ** ** *******************************************************************/static int arca_prn_paper_forward(unsigned int steps){ if (steps > 24) { pmotor_steps = steps - 24; ENCODE_STATUS(PRN_PAPERFETCH2, MOTOR_STAT_ACC, NPMOTOR); } else { pmotor_steps = steps; //置慢速标志 ENCODE_STATUS(PRN_PAPERFETCH2, MOTOR_STAT_COIL, NPMOTOR); } __prn_pmotor_irq_unmask(); return 0;}/******************************************************************* ** ** *******************************************************************/static int arca_prn_paper_fallback(unsigned int steps){ if (steps > 24) { pmotor_steps = steps - 24; ENCODE_STATUS(PRN_PAPERFETCH2, MOTOR_STAT_ACC, NPMOTOR); } else { pmotor_steps = steps; ENCODE_STATUS(PRN_PAPERFETCH2, MOTOR_STAT_COIL, NPMOTOR); } pmotor_direction = 0; __prn_pmotor_irq_unmask(); return 0;}/******************************************************************* ** For module ** *******************************************************************/struct prn_dev { int opened; void *private;};static struct prn_dev prn;static unsigned char prn_dev_minor = 3;static struct timer_list prn_timer;static int arca_prn_open(struct inode *inode, struct file *filp);static int arca_prn_release(struct inode *inode, struct file *filp);static int arca_prn_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);static ssize_t arca_prn_write(struct file *filp, const char *buf, size_t count, loff_t *ppos);static struct file_operations arca_prn_fops ={ write: arca_prn_write, ioctl: arca_prn_ioctl, open: arca_prn_open, release: arca_prn_release};/******************************************************************* ** Motor state mechanism ** *******************************************************************/static void prn_decode_motor_state(unsigned char status, unsigned char motor){ switch (motor) { case NCMOTOR: switch (status) { case MOTOR_STAT_STOP: prn_cmotor_stop(cmotor_direction); break; case MOTOR_STAT_ACC: prn_cmotor_acc(cmotor_direction); break; case MOTOR_STAT_CONST: prn_cmotor_const(cmotor_direction); break; case MOTOR_STAT_COIL: __prn_cmotor_data2irq_unmask(); prn_cmotor_coil(cmotor_direction); break; case MOTOR_STAT_DEC: prn_cmotor_dec(cmotor_direction); break; case MOTOR_STAT_WORKRUSH: prn_cmotor_work_rush(cmotor_direction); break; case MOTOR_STAT_HOLDRUSH: prn_cmotor_hold_rush(cmotor_direction); break; } break; case NPMOTOR: switch (status) { case MOTOR_STAT_STOP: prn_pmotor_stop(pmotor_direction); break; case MOTOR_STAT_ACC: prn_pmotor_acc(pmotor_direction); break; case MOTOR_STAT_CONST: prn_pmotor_const(pmotor_direction); break; case MOTOR_STAT_COIL: prn_pmotor_coil(pmotor_direction); break; case MOTOR_STAT_DEC: prn_pmotor_dec(pmotor_direction); break; case MOTOR_STAT_STEP: prn_pmotor_step(pmotor_direction); break; } break; }}/******************************************************************* ** ** *******************************************************************/static void arca_prn_interrupt(int irq, void *dev_id, struct pt_regs *regs){ switch (PRN_STATUS()) { case PRN_BLACKMARK: case PRN_NEWLINE: case PRN_PRINTING: case PRN_PAPERFETCH0: case PRN_PAPERFETCH1: case PRN_PAPERFETCH2: prn_decode_motor_state(MOTOR_STATUS(), MOTOR_NUM()); break; default: __prn_irq_mask(); break; }}/******************************************************************* ** ** *******************************************************************/static int arca_prn_open(struct inode *inode, struct file *filp){ if (prn.opened) { printk(KERN_INFO "arca_prn: The device BUSY\n"); return -EBUSY; } prn.opened = 1; if ( (filp->f_flags & O_ACCMODE) == O_RDONLY ) printk(KERN_INFO "arca_prn: Need use WR to access this device.\n"); return 0;}/******************************************************************* ** ** *******************************************************************/static int arca_prn_release(struct inode *inode, struct file *filp){ prn.opened = 0; return 0;}/******************************************************************* ** ** *******************************************************************/static int arca_prn_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ sigset_t orig_sigmask; int rc = 0; if (PRN_STATUS() != PRN_STANDBY) if ((PRN_STATUS() != PRN_RST1) || (cmd != PRNIORESET)) return -EFAULT; if (__prn_paper_end() && (PRN_STATUS() != PRN_RST1)) { ENCODE_STATUS(PRN_PAPERFETCH1, MOTOR_STAT_ACC, NPMOTOR); __prn_cmotor_irq_mask(); __prn_pmotor_irq_unmask(); return -EFAULT; } switch (cmd) { case PRNIOPOWEROFF: REG8(PRN_PMOTOR_PORT1) = 127; REG8(PRN_PMOTOR_PORT2) = off_i | motor_steps[pmotor_step % 4]; REG8(PRN_CMOTOR_PORT1) = 127; REG8(PRN_CMOTOR_PORT2) = off_i | motor_steps[cmotor_step % 4]; return rc; case PRNIORESET: ENCODE_STATUS(PRN_RST1, 0, 0); if (arca_prn_reset()) return -EIO; ENCODE_STATUS(PRN_STANDBY, 0, 0); return rc; case PRNIOBLKMARK: arca_prn_blackmark(); break; case PRNIONEWLINE: arca_prn_newline(); break; case PRNIOPAPERFW: arca_prn_paper_forward(arg); break; case PRNIOPAPERFB: arca_prn_paper_fallback(arg); break; default: break; } orig_sigmask = current->blocked; sigaddsetmask(¤t->blocked,~_DONT_BLOCK); recalc_sigpending(current); interruptible_sleep_on(&prn_wait_queue); current->blocked = orig_sigmask; if (signal_pending(current)) { ENCODE_STATUS(PRN_STANDBY, 0, 0); recalc_sigpending(current); return -EFAULT; } recalc_sigpending(current); if (PRN_STATUS() == PRN_RST0) return -EFAULT; ENCODE_STATUS(PRN_STANDBY, 0, 0); return rc;}/******************************************************************* ** ** *******************************************************************/static ssize_t arca_prn_write(struct file *filp, const char *buf, size_t count, loff_t *ppos){ sigset_t orig_sigmask; __prn_irq_mask(); /* Add for security -- spark 2004.12.23 */ // 判断是否处于可打印阶段 if (PRN_STATUS() != PRN_STANDBY) return -EFAULT; // 判断是否缺纸 if (__prn_paper_end()) { ENCODE_STATUS(PRN_PAPERFETCH1, MOTOR_STAT_ACC, NPMOTOR); __prn_cmotor_irq_mask(); __prn_pmotor_irq_unmask(); return -EFAULT; } // 拷贝数据 if (copy_from_user(prn_buffer, buf, count)) return -EFAULT; prn_line_max_steps = count >> 2; old_val = 0; ENCODE_STATUS(PRN_PRINTING, MOTOR_STAT_WORKRUSH, NCMOTOR); __prn_cmotor_irq_unmask(); orig_sigmask = current->blocked; sigaddsetmask(¤t->blocked,~_DONT_BLOCK); recalc_sigpending(current); interruptible_sleep_on(&prn_wait_queue); current->blocked = orig_sigmask; if (signal_pending(current)) { ENCODE_STATUS(PRN_STANDBY, 0, 0); recalc_sigpending(current); return -EFAULT; } recalc_sigpending(current); ENCODE_STATUS(PRN_STANDBY, 0, 0); return count;}/******************************************************************* ** ** *******************************************************************/static unsigned char trigger_count = 0;static void prn_timer_routine(unsigned long dummy){ if ((PRN_STATUS() == PRN_RST0) && (!__prn_paper_end())) { trigger_count ++; if (trigger_count >= 3) { dprintk("Find paper, enable interrupt.\n"); trigger_count = 0; if (arca_prn_reset()) ENCODE_STATUS(PRN_RST0, 0, 0); else { ENCODE_STATUS(PRN_PAPERFETCH0, MOTOR_STAT_ACC, NPMOTOR); __prn_pmotor_irq_unmask(); } } } if ((__prn_paper_end()) && (PRN_STATUS() == PRN_STANDBY)) ENCODE_STATUS(PRN_RST0, 0, 0); if (__prn_paper_end()) trigger_count = 0; if ((PRN_STATUS() == PRN_STANDBY) || (PRN_STATUS() == PRN_RST0) || (PRN_STATUS() == PRN_RST1)) { REG8(PRN_PMOTOR_PORT1) = 127; REG8(PRN_PMOTOR_PORT2) = off_i | motor_steps[pmotor_step % 4]; REG8(PRN_CMOTOR_PORT1) = 127; REG8(PRN_CMOTOR_PORT2) = off_i | motor_steps[cmotor_step % 4]; } init_timer(&prn_timer); prn_timer.expires = jiffies + PRN_TIMER; prn_timer.data = 0; prn_timer.function = prn_timer_routine; add_timer(&prn_timer);}/******************************************************************* ** ** *******************************************************************/static int __init arca_prn_init(void){ int result; prn.opened = 0; __prn_irq_mask(); if (request_irq(PRN_IRQ, arca_prn_interrupt, SA_INTERRUPT, "arca_prn", &prn)) { printk(KERN_INFO "arca_prn: IRQ %d is in used.\n", PRN_IRQ); free_irq(PRN_IRQ, &prn); return -ENODEV; } result = arca_register_chrdev(prn_dev_minor, "arca_prn", &arca_prn_fops, &prn); __prn_pin_init(); if (__prn_paper_end()) ENCODE_STATUS(PRN_RST0, 0, 0); else { if (arca_prn_reset()) ENCODE_STATUS(PRN_RST1, 0, 0); else ENCODE_STATUS(PRN_STANDBY, 0, 0); } init_timer(&prn_timer); prn_timer.expires = jiffies + PRN_TIMER; prn_timer.data = 0; prn_timer.function = prn_timer_routine; add_timer(&prn_timer); printk("arca_prn: Arca printer driver launched \n"); return 0;}/******************************************************************* ** ** *******************************************************************/static void __exit arca_prn_exit(void){ free_irq(PRN_IRQ, &prn); del_timer(&prn_timer); arca_unregister_chrdev(prn_dev_minor, "arca_prn");}MODULE_AUTHOR ("Seeger Chin <lqin@arca.com.cn>");MODULE_DESCRIPTION ("Arca printer driver");MODULE_LICENSE("ARCANDA");MODULE_PARM (debug, "i");module_init(arca_prn_init);module_exit(arca_prn_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -