📄 u110.c
字号:
/******************************************************************** * M-U110Ⅱ+ printer/linux-driver/MU1102.c * * Arca FCR1.2 platform PRN Driver. (Epson M-U110Ⅱ) * Author: 叶华峰 * Owner: START Technology Corp. * Date: 2005.09.28 ********************************************************************/#include <linux/config.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/serial.h>#include <linux/major.h>#include <linux/string.h>#include <linux/fcntl.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/fs.h>#include <linux/slab.h>#include <linux/spinlock.h>#include <linux/arca-chars.h>#include <asm/system.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <asm/bitops.h>#include <asm/processor.h>#include <asm/hardware.h>/******************************************************************* ** ** *******************************************************************/#define EM_EER 0#define EM_OK 1#define PRNIORESET 0x19750000#define PRNIOBLKMARK 0x19750001#define PRNIONEWLINE 0x19750002#define PRNIOPAPERFW 0x19750003#define PRNIOPAPERFB 0x19750004#define PRNIOPOWEROFF 0x19750005#define PRN_TIMER (1 * HZ)#define DEBUG 0#if DEBUG#define dprintk(x...) if (DEBUG) printk(x)#else#define dprintk(x...)#endif#if defined(CONFIG_ARCA_FCR12_PLATFORM)#define PRN_COIL_REG 0xaf000000#define PRN_CMOTOR_PORT1 0xaf400000#define PRN_CMOTOR_PORT2 0xaf600000#define PRN_PMOTOR_PORT1 0xaf800000#define PRN_PMOTOR_PORT2 0xafa00000#define PRN_STATUS_REG 0xafc00000#define PRN_IRQM_REG 0xafc00000#define STATUS_PMOTOR_READY (1 << 6) // 1左移6位 0100,0000#define STATUS_CMOTOR_READY (1 << 5) // 1左移6位 0010,0000#define STATUS_COIL_READY (1 << 4) // 1左移6位 0001,0000#define STATUS_BLACKMARK (1 << 3) // 1左移6位 0000,1000#define STATUS_PAPER_END (1 << 2) // 1左移6位 0000,0100#define STATUS_HOME_POSITION (1 << 1) // 1左移6位 0000,0010#define STATUS_CARRIAGE_HOT (1 << 0) // 1左移6位 0000,0001#ifndef REG8#define REG8(n) (*(volatile unsigned char *)(n))#endif#define EM_SET1(ucRegister,temp) do { ucRegister=(ucRegister|temp) } while (0)#define EM_CLR0(ucRegister,temp) do { ucRegister=(ucRegister&temp) } while (0)#define __prn_pmotor_ready() (REG8(PRN_STATUS_REG) & STATUS_PMOTOR_READY)#define __prn_cmotor_ready() (REG8(PRN_STATUS_REG) & STATUS_CMOTOR_READY)#define __prn_coil_ready() (REG8(PRN_STATUS_REG) & STATUS_COIL_READY)#define __prn_blackmark() (!(REG8(PRN_STATUS_REG) & STATUS_BLACKMARK)//没有中断时为1。有中断时为0#define __prn_paper_end() (!(REG8(PRN_STATUS_REG) & STATUS_PAPER_END))#define __prn_carriage_hot() (REG8(PRN_STATUS_REG) & STATUS_CARRIAGE_HOT)static volatile unsigned char prn_irq = 0;static unsigned char old_val=0; /* For test */static unsigned char tmpp=0; /* Nick *//* How many steps the c-motor will walk to print the current line. */static volatile int prn_line_max_steps=0; #define _NEVER_BLOCK (sigmask(SIGKILL) | sigmask(SIGSTOP))#define _DONT_BLOCK (_NEVER_BLOCK | sigmask(SIGINT))/******************************************************************* **prn_irq为中断标志寄存器 D0位字车电机中断 ** D0位 字车电机中断标志位 1:发生中断 0:没有中断 ** D1位 给纸电机中断标志位 1:发生中断 0:没有中断 ** D2位 字车电机data2中断标志位 1:发生中断 0:没有中断 ** *******************************************************************/#define __prn_cmotor_irq_mask() \do { \ prn_irq |= 0x01; \// D0位置1 REG8(PRN_STATUS_REG) = prn_irq; \//REG8(abc)表示abc地址值 udelay(1); \} while (0)#define __prn_cmotor_irq_unmask() \do { \ prn_irq &= ~0x01; \// D0位置0 REG8(PRN_STATUS_REG) = prn_irq; \ udelay(1); \} while (0)#define __prn_cmotor_data2irq_mask() \do { \ prn_irq |= 0x04; \ REG8(PRN_STATUS_REG) = prn_irq; \ udelay(1); \} while (0)#define __prn_cmotor_data2irq_unmask() \do { \ prn_irq &= ~0x04; \ REG8(PRN_STATUS_REG) = prn_irq; \ udelay(1); \} while (0)#define __prn_pmotor_irq_mask() \do { \ prn_irq |= 0x02; \ REG8(PRN_STATUS_REG) = prn_irq; \ udelay(1); \} while (0)#define __prn_pmotor_irq_unmask() \do { \ prn_irq &= ~0x02; \ REG8(PRN_STATUS_REG) = prn_irq; \ udelay(1); \} while (0)#define __prn_irq_mask() \do { prn_irq |= 0x07; \//有中断发生D2D1D0 置111 有中断发生 REG8(PRN_STATUS_REG) = prn_irq; \ udelay(1); \} while (0)#define __prn_pin_init() \do { \ __gpiob_as_intr(7); \///?????????? __gpiob_set_irq_high_level(7); \ udelay(1); \} while(0)/******************************************************************* ** ** *******************************************************************/#define PRN_IRQ INTC_IRQ7#else#error "Not supported platform"#endif//电流标志static unsigned char off_i = 0x0c;static unsigned char hold_i = 0x08;static unsigned char prun_i = 0x00;//给纸电机运行电流标志static unsigned char crun_i = 0x00;//字车电机运行电流标志static volatile unsigned int cmotor_step = 0x80000000; /*volatile 在每次访问时,其值被重载 */static volatile unsigned int pmotor_step = 0x80000000;static volatile unsigned char prn_state;static volatile unsigned char cmotor_direction = 0;static volatile unsigned char pmotor_direction = 0;static volatile unsigned int pmotor_steps;static unsigned char cmotor_const_param = 0;#define PRN_RST0 0x10 //#define PRN_RST1 0x20#define PRN_STANDBY 0x30 // #define PRN_BLACKMARK 0x40 //黑标#define PRN_NEWLINE 0x50 //新行#define PRN_PRINTING 0x60 //正在打印#define PRN_PAPERFETCH0 0x70#define PRN_PAPERFETCH1 0x80#define PRN_PAPERFETCH2 0x90#define MOTOR_STAT_STOP 0x00#define MOTOR_STAT_ACC 0x01#define MOTOR_STAT_CONST 0x02#define MOTOR_STAT_COIL 0x03 //???#define MOTOR_STAT_DEC 0x04#define MOTOR_STAT_WORKRUSH 0x05 //前rush #define MOTOR_STAT_HOLDRUSH 0x06 //后rush#define MOTOR_STAT_STEP 0x07 //???#define NPMOTOR 0x01#define NCMOTOR 0x00 //prn_state的#define PRN_STATUS() ((prn_state) & 0xf0) //为高4位D7-D4#define MOTOR_STATUS() (((prn_state) & 0x0f) >> 1)//为低前3位D3-D1#define MOTOR_NUM() ((prn_state) & 0x01) //位D0#define DATA2INTERUPT() ((prn_state) & 0x10) //位D4#define ENCODE_STATUS(prns, motors, motor) \do { \ prn_state = (prns) | ((motors) << 1) | ((motor) & 0x01); \} while (0)static unsigned char prn_buffer[4096];/******************************************************************* ** ** *******************************************************************/static unsigned char motor_steps[] = { 0x00, 0x02, 0x03, 0x01 };//含义根据步数改变相位。 //因为4步为一个周期static unsigned char cmotor_acc[11] = { 58, 28, 22, 19, 17, 16, 15, 15, 14, 13, 12};static unsigned char cmotor_dec[11] = { 12, 13, 13, 14, 15, 17, 18, 21, 25, 32, 78};static unsigned char pmotor_acc[21] = { 82, 54, 42, 35, 31, 28, 26, 24, 23, 21, 20, 19, 19, 18, 17, 17, 16, 16, 15, 15, 15};static unsigned char pmotor_dec[3] = { 15, 20, 29};static volatile unsigned int coil_counter = 0;/******************************************************************* ** 函数定义 ** *******************************************************************//* 通用函数定义 */static void EI_vDelay(UINT16 uiNum);/* 字车电机函数定义 */static void EI_vCMworkrush(void); static void EI_vCMHoldrush(void); static void EI_vCMHold(void); static UINT8 EI_vCMIni(void); static void EI_vCMIniRun(UINT8 ucDir);static void EI_vCMIniAcc(UINT8 ucDir);static void EI_vCMIniConst(UINT8 ucDir,UINT16 uiNum,UINT8 ucTest);static void EI_vCMIniDec(UINT8 ucDir);static void EI_vCMRun(UINT8 ucDir,UINT16 uiNum);static void EI_vCMAcc(UINT8 ucDir);static void EI_vCMConst(UINT8 ucDir);static void EI_vCMPrint(UINT8 ucDir);static void EI_vCMLow(UINT8 ucDir);static void EI_vCMDec(UINT8 ucDir);static void/* 给纸电机函数定义 */static void EI_vPFRun(UINT8 ucDir,UINT16 uiNum);static void EI_vPFworkrush(void); static void EI_vPFHoldrush(void); static void EI_vPFHold(void); static void EI_vPFAcc(UINT8 ucDir); static void EI_vPFConst(UINT8 ucDir); static void EI_vPFDec(UINT8 ucDir); static void EI_vPFLow(UINT8 ucDir); /* 打印机驱动控制端口层函数定义 */static UINT8 EI_ucGetHPS(void); //读HPSstatic void EI_vCMProtI(UINT8 ucCur) //CM电流保护static void EI_vCMPhOut(UINT8 ucPhase); //置CM相位static void EI_vCMIOut(UINT8 ucCur); //置CM电流static void EI_vSetTimer20(ucTime); //置Timer20比较器时间static UINT8 EI_ucGetTimer20(void)static void EI_vCMIOut 字车电机电流输出static void EI_vSetTimer20 置Timer20/***************************************************************** * 字车电机初始化各状态函数 *****************************************************************///宏定义#define EM_RushTime //电机Rush时间 // M-U110Ⅱ+:5ms;M-U110:6ms;MU-130:6ms#define EM_CMIniAorDStp //字车电机初始化时最大加、减步数#define EM_CMIniConTime //字车电机初始化时匀速时间 // M-U110Ⅱ+:1.05ms;M-U110:1.05ms;MU-130:0.91ms //全局变量定义static UINT8 EG_MotorPh[4] = { 0x00, 0x02, 0x03, 0x01 }; static UINT8 EG_CMIniAccTM[10] = {58, 28, 22, 19, 17, 16, 15, 15, 14, 13, 12};static UINT8 EG_CMIniDecTM[10] = {12, 13, 13, 14, 15, 17, 18, 21, 25, 32, 78};static UINT8 EG_CMDirstatic UINT16 EG_CMNum=0x80000000 //字车电机位置 static UINT8 EI_vCMIni(void){ UINT16 uiR=0; if (!EI_ucGetHPS()) { EI_vCMworkrush(); EI_vCMIniAcc(1); uiR = EI_vCMIniConst(1,240, 1); if (uiR==240){ print("Error: CM can not reset home position!\n"); return EM_ERR; } EI_vCMIniConst(1, 22-EM_CMIniAorDStp, 0) EI_vCMIniDec(1); EI_vCMHoldrush(); EI_vCMHold(); } EI_vCMworkrush(); EI_vCMIniAcc(0); EI_vCMIniConst(0, 32, 0) EI_vCMIniDec(0); EI_vCMHoldrush(); EI_vCMHold(); if (EI_ucGetHPS()){ print("Error: CM can not reset home position!\n"); return EM_ERR; } EI_vCMworkrush(); EI_vCMIniAcc(1); uiR = EI_vCMIniConst(1,32,1); if (uiR==32){ print("Error: CM can not reset home position!\n"); return EM_ERR; } EI_vCMIniConst(1,12, 0) EI_vCMIniDec(1); EI_vCMHoldrush(); EI_vCMHold(); if(EG_PaperType) // EG_CMNum=358; else EG_CMNum=420; return EM_OK;} static void EI_vCMIniAcc(UINT8 ucDir);{ INT8 ucTime; INT8 ucPhase; INT8 cStep = (ucDir) ? 1 : -1; UINT16 uiI; for (ucI=0;uiI<EM_CMIniAorDStp;uiI++) { EG_CMNum += cStep; ucTime = EG_CMIniAccTM[uiI]; ucPhase = EG_MoterPh[EG_CMNum % 4];// EI_vSetTimer20(ucTime); EI_vCMPhOut(ucPhase); while (!EI_ucGetTimer20()) //查询中断方式 EI_vDelay(500); }}//初始化匀速阶段static UINT16 EI_vCMIniConst(UINT8 ucDir,UINT16 uiNum,UINT8 ucTest){ INT8 ucTime; INT8 ucPhase; INT8 cStep = (ucDir) ? 1 : -1; UINT16 uiI; for (ucI=0;uiI<uiNum;uiI++) { if ((ucTest == 1) && (EI_vGetHPS())) return ucI; else if ((ucTest == 2) && (EI_vGetHPS())) return ucI; EG_CMNum += cStep; ucTime = EM_CMIniConTime; ucPhase = EG_MoterPh[EG_CMNum % 4]; EI_vSetTimer20(ucTime); EI_vCMPhOut(ucPhase); } return uiNum; }//初始化减速阶段static void EI_vCMIniDec(UINT8 ucDir){ INT8 ucTime; INT8 ucPhase; INT8 cStep = (ucDir) ? 1 : -1; UINT16 uiI; for (ucI=0;uiI<EM_CMIniAorDStp;uiI++) { EG_CMNum += cStep; ucTime = EG_CMIniDecTM[uiI]; ucPhase = EG_MoterPh[EG_CMNum % 4];// EI_vSetTimer20(ucTime); EI_vCMPhOut(ucPhase); } return;}static void arca_prn_hp_hold(void){ unsigned char port2; port2 = hold_i | motor_steps[cmotor_step % 4]; //must hold motor state hold_i = 0x08 while (!__prn_cmotor_ready()) udelay(500); REG8(PRN_CMOTOR_PORT2) = port2; udelay (12000); return;}/******************************************************************* ** **此rush函数用于减速或慢速后的rush状态 *******************************************************************/static void arca_prn_hold_rush(void){ unsigned char port2; port2 = crun_i | motor_steps[cmotor_step % 4]; //must hold motor state while (!__prn_cmotor_ready())//REG8(PRN_STATUS_REG) & STATUS_CMOTOR_READY udelay(500); REG8(PRN_CMOTOR_PORT2) = port2; udelay (6000); return;}/******************************************************************* ** **此rush函数用于加速或慢速前的rush状态,改变电流 *******************************************************************/static void arca_prn_work_rush(void){ unsigned char port2; port2 = crun_i | motor_steps[cmotor_step % 4]; //must hold motor state while (!__prn_cmotor_ready()) udelay(500); REG8(PRN_CMOTOR_PORT2) = port2; udelay (6000); return;}/******************************************************************* ** **
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -