📄 prn_drv.c
字号:
/*----------------------------------------------------------
* Printer Driver program
*---------------------------------------------------------*/
#include "ecrsys.h"
#include "ftype.h"
#include "data.h"
#include "sysdata.h"
#include <string.h>
void CvtBmp(void);
void CalcuDotNum(void);
WORD th_temp_get(void);
void Prn_Step_Feed(void);
void Send_Dot_DMA_Buff(byte flag);
void CvtBmpCompress(const byte *src);
void CvtBmpNormal(const byte *src);
#define MAX_HEAT_DOT_CNTR 128
//#define MAX_HEAT_DOT_CNTR 384
volatile static CHR *prn_curr_dot_ptr, Prn_Step_Base;
volatile static WORD Ta2_Intvl;
volatile CHR Prn_Stat;
#define DOT_DOUBLE_BASE (byte *)(0xfc0000 + 0x38000 + 48 * 256)
const byte zeroData[MAX_CNTR_PRN_HEAD] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define HEAT_1000 1000 * FOSC / 8
#define HEAT_800 800 * FOSC / 8
#define HEAT_750 750 * FOSC / 8
#define HEAT_700 700 * FOSC / 8
#define HEAT_600 600 * FOSC / 8
#define HEAT_500 500 * FOSC / 8
#define HEAT_300 300 * FOSC / 8
long dmaDataAddr;
byte bkDotRing[49][55];
byte tmpDotBuffer[49][55];
byte bkphead = 0;
#define PAPER_END_ERR 1
const word feedTime[] = {
// 1500, 1400, 1300, 1200, 1000, 800, 800, 800, 800, 800, 800, 800,
// 800, 800, 800, 800, 800, 800, 800, 1000, 1200, 1300, 1400, 1500,
1500, 1200, 1000, 850, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 850, 1000, 1200, 1500,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800,
800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800
};
/* Wait printer buffer empty and printer stop to IDLE mode */
void wait_prn_Stop(void)
{
DEBUG_PRN(return;)
while(1)
{
prn_Chk();
if( (phead == prear) && ( Prn_Stat == PRN_IDLE))
break;
}
}
/*****************************************************************************************
* Printer paper end,
* Only allow user depress the FEED key and Clear key.
*
* Feed --- > For feed paper.
* Clear --- > For relese the paper end error.
*****************************************************************************************/
void prn_papr_end(void)
{
word key;
prn_flag.papr_end = TRUE;
Clr_Period();
Disp_Spec_Period();
dis_sto_last_disp();
Clr_All_Dsp_Data(FALSE);
disp_Char_Str(Disp_Papr_Out,0);
bellcnt = 0xfe;
while( 1 )
{
if ( Key_Poll_Chk() )
{
key = GetKey( );
if ( key == KD_FEED ) //Feed 1 character line.
{
disint();
Prn_Stat = PRN_FEED;
Ttl_Fd_line = NM_FEED_PAPER;
PrnVccOn();
VPR_ON();
enint();
}
else if ( key == KD_CLEAR ) //Release the paper end error.
{
if ( PRN_PEND == 0 )
{
Clr_Dsp_Data();
Insert_Num(0, 8);
// Comm_Disp();
// // add print last line before paper end
// if (Prn_Last_Line_Paper_End() == PAPER_END_ERR)
// {
// Clr_Dsp_Data();
// disp_Char_Str("PAPR OUT ---",0);
// bellcnt = 0xfe;
// continue;
// }
prn_flag.papr_end = FALSE;
break;
}
}
}
if ( prn_flag.prn_break == 1 ) //Printer open flag.
{
// Fm_Events_Prn_Disc();
// Sys_Halt(ERR_PRN_DSCNT);
}
}
en_sto_last_disp();
Lcm_Disp_Last_Line(LCM_LINE_2);
}
/*****************************************************************************************
* For safely use the printer, we have to check the following:
* 1. Check the Paper end sensor,
* 2. Check the Temprature of the printer.
* 3. Check whethre the printer is connected, if not, then must do the printer disconnection.
* 02-11-17 16:49 By ZhengXiaoChun
* Note: This routine should be called when do the printer dot converting proces.
******************************************************************************************/
void prn_Chk( void )
{
CHR i ;
DEBUG_PRN(
return;
);
if ( prn_flag.prn_break == 1 ) //Printer open flag.
{
// Fm_Events_Prn_Disc();
// Sys_Halt(ERR_PRN_DSCNT);
}
// if ( ( PRN_PEND == 1 ) && ( prear != phead ))
if ( PRN_PEND == 1 )
prn_papr_end();
}
/******************************************************************************
* Describe: convert Normal string to dot-matrix buffer
* Input : void
* Output: void
* return: void
******************************************************************************/
const byte kValue[33] = {0, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29,
31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47, 49, 50, 52, 53 };
/******************************************************************************
* Describe: calculate dot num per dot line, and separate there into 6 part.
* Input : void
* Output: void
* return: void
******************************************************************************/
void CalcuDotNum(void)
{
byte i, j, k, idx, dotNum, dataCnt;
byte tmpDotNum;
byte *ptr;
for (i=0,idx=phead; i<24; i++,idx++)
{
Prn_Dot_Ring[idx][0] = NM_DOT_FD_CNTR;
}
return;
// calculate need send times and data length every dot line
for ( i=0,idx=phead; i<24; i++,idx++ )
{
ptr = Prn_Dot_Ring[idx];
*ptr = NM_DOT_FD_CNTR; // two step is one dot line
// calculate (dot sum < 64)'s data length
dotNum = 0;
k = 1;
dataCnt = 0;
ptr += 7;
for (j=7; j<55; j++)
{
tmpDotNum = dotNum;
dotNum += DotNumArray[*ptr++];
dataCnt++; // data lenth
if (dotNum >= MAX_HEAT_DOT_CNTR )
{
if (dotNum == MAX_HEAT_DOT_CNTR )
{
dotNum = 0;
Prn_Dot_Ring[idx][k] = dataCnt;
dataCnt = 0;
}
else
{
dotNum -= tmpDotNum;
Prn_Dot_Ring[idx][k] = dataCnt - 1;
dataCnt = 1;
}
k++;
}
}
// if ((dataCnt != 0) && (dotNum != 0))
if (dataCnt != 0)
{
Prn_Dot_Ring[idx][k] = dataCnt;
k++;
}
for ( ; k<7; k++)
{
Prn_Dot_Ring[idx][k] = 0;
}
}
}
#define HEAT_TM 800
volatile static CHR *prn_curr_dot_ptr, Prn_Step_Base;
CHR Total_Dot_Cntr = 0;
CHR Heat_Cntr = 0;
/******************************************************************************
* Describe: Interrupt for timer A2 used for the heating processing.(TIME A2 ISR )
* Input : void
* Output: void
* return: void
******************************************************************************/
void HeatTimer( void )
{
if (Prn_Stat == PRN_HEAT)
{
Prn_Stat = PRN_FEED;
ta4s = 0;
ta4 = 10;
ta4s = 1;
STB1 = STB2 = 1; // Off all STB segment.
}
ta2s = 0; // Disable the Timer A2.
}
/******************************************************************************
* Describe: Timer A4 (paper feed Timer) ISR
* Input : void
* Output: void
* return: void
******************************************************************************/
extern byte pause_Prn;
extern byte currCloseFlag;
extern byte prnThPause;
byte feedStep = 0;
word feedTime1 = 3000 * FOSC / 8;
word feedTime2 = 1000 * FOSC / 8;
byte volatile feedFlag = 0;
byte volatile sendDataFlag = 0;
#define STEP_TIME 700
void PaperFeedTimer(void)
{
byte tmp;
static byte feedCnt = 0;
word time;
ta4s = 0;
ta4 = STEP_TIME * FOSC / 8;
ta4s = 1;
ir_ta4ic = 0; // 防止由于中断响应延迟,两次步进时间间隔太短.
if (prnThPause)
{
STB1 = STB2 = 1; // Off all STB segment.
STEP_OFF();
return;
}
if (pause_Prn) // succesive print time exceed 30s, need cool 5 ~ 10 s
{
STB1 = STB2 = 1; // Off all STB segment.
currCloseFlag = 0;
STEP_OFF();
return;
}
if (Prn_Stat == PRN_PROTECT) // 过热保护,暂停加热,直至温度降低.
{
if (th_temp_get() != NG)
{
Prn_Stat = PRN_HEAT;
}
}
if (Prn_Stat == PRN_HEAT) // heat timer function
{
Prn_Stat = PRN_FEED;
STB1 = STB2 = 1; // Off all STB segment.
}
if (Prn_Stat == PRN_FEED)
{
if (Ttl_Fd_line == 0) // All feed line finish.
{
feedFlag = 0;
sendDataFlag = 0;
Prn_Stat = PRN_IDLE;
VPR_OFF();
PrnVccOff();
}
else if (Ttl_Fd_line == 1)
{
Prn_Step_Feed();
Ttl_Fd_line --;
if (phead != prear) // schdule
{
prn_curr_dot_ptr = (CHR*)&Prn_Dot_Ring[prear][0];
Ttl_Fd_line = *prn_curr_dot_ptr ++;
if (Ttl_Fd_line == NM_DOT_FD_CNTR) // Normal data printing.
{
sendDataFlag = 1;
Send_Dot_DMA_Buff(1); // Start the dot sending.
}
else
{
sendDataFlag = 0;
if (Ttl_Fd_line != NM_CHA_SP_CNTR) // 非字符行间隔.
{
feedFlag = 1;
}
Send_Dot_DMA_Buff(3);
}
prear++;
}
}
else if (Ttl_Fd_line == 2)
{
Ttl_Fd_line --;
if (sendDataFlag == 1) // send data & heat
{
Send_Dot_DMA_Buff(2); // Start the dot sending.
}
else
{
Send_Dot_DMA_Buff(3);
}
Prn_Step_Feed();
}
else
{
Ttl_Fd_line --;
Send_Dot_DMA_Buff(3);
Prn_Step_Feed();
}
feedCnt = 0;
currCloseFlag = 1;
}
else if (feedCnt < 10) // only for continued print protect
{
STEP_OFF();
feedCnt++;
}
else
{
STEP_OFF();
currCloseFlag = 0;
}
if ((Prn_Stat == PRN_IDLE) && (phead != prear))
{
prn_schedule();
}
}
/******************************************************************************
* Describe:
* Input : void
* Output: void
* return: void
******************************************************************************/
void Prn_Step_Feed(void)
{
// WD2-KR主板与WD1主板,两个驱动端口顺序相反.
const byte cw_data[4] = {0x00, 0x10, 0x18, 0x08};
prn_step ++;
if (prn_step >= 4)
prn_step = 0;
// On motor & set phase
STEP_ON();
g_Cs_Drive &= 0xE7;
g_Cs_Drive |= cw_data[prn_step];
CS_DRIVE = g_Cs_Drive;
if ((sysflag->fl_wmotor) && (sysflag->set_timmer != 0))
{
WMTOR = 1;
wmtor_timmer = sysflag->set_timmer;
}
}
void prn_schedule(void)
{
if ((phead != prear) && (Prn_Stat == PRN_IDLE)) // Exist data need print.
{
// if (prn_flag.prn_break || prn_flag.temp_high || prn_flag.papr_end)
// {
// return;
// }
if ((prn_flag.papr_end) || (PRN_TH == 1))
{
return;
}
PrnVccOn();
VPR_ON();
prn_curr_dot_ptr = (CHR*)&Prn_Dot_Ring[prear][0];
Ttl_Fd_line = *prn_curr_dot_ptr ++;
if ((Ttl_Fd_line == NM_DOT_FD_CNTR)) // Normal data printing.
{
sendDataFlag = 1;
Send_Dot_DMA_Buff(1); // Start the dot sending.
}
else
{
// if (Ttl_Fd_line == NM_CHA_SP_CNTR)
{
Prn_Stat = PRN_FEED;
Prn_Step_Feed(); // Feed 1-step.
Ttl_Fd_line--;
sendDataFlag = 0;
if (Ttl_Fd_line != NM_CHA_SP_CNTR)
{
feedFlag = 1;
}
}
}
prear ++;
}
}
/******************************************************************************
* Describe:Send the Dot to DMA buffer accoring to the buffer information.
* Input : void
* Output: void
* return: void
******************************************************************************/
void Send_Dot_DMA_Buff(byte flag)
{
if (flag == 1)
{
dmaDataAddr = (long)&prn_curr_dot_ptr[7];
dmaTranLen = 47;
#pragma ASM
ldc _dmaDataAddr, dma0
ldc _dmaTranLen, dct0
#pragma ENDASM
u4tb = prn_curr_dot_ptr[6]; // start sending.
Prn_Stat = PRN_SEND;
}
else if (flag == 2)
{
STB2 = 0;
Prn_Latch = 0;
Prn_Stat = PRN_HEAT;
Prn_Latch = 1;
Ta2_Intvl = th_temp_get();
if (Ta2_Intvl == NG)
{
Prn_Stat = PRN_PROTECT; // 过热保护.
STB2 = 1;
return;
}
ta4s = 0;
// ta4 = 500 * FOSC / 8;
ta4 = Ta2_Intvl;
ta4s = 1; // Start timer A2
}
else
{
// if (feedFlag == 1) // User Feed Operation
// {
// ta4s = 0;
// ta4 = feedTime[Ttl_Fd_line] * FOSC / 8;
//// ta4 = 800 * FOSC / 8;
// ta4s = 1;
// }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -