?? 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 + -