Hello.
I am coding to build-up SDLC(HDLC) in z85c30 with MCU,
ATmega128.
I am trying to build-up SDLC(HDLC) protocal
H/w environment is z85c30(CMOS) with 4.91520Mhz crystal for PCLK.
Also, z85c30's D0~D7 is connected with MCU in un-multiplexed
mode(=direct)
communication specification is as below
- 38.4kbps
- NRZI mode
- Response time: 50ms
- Address: Lower=70h Higher=05h
- control field: 13h
- Information field
if first text = 20, SDR(Master -> Slave)
if first text = 30, SD(Slave -> Master)
For SDR, Information field length is 20 + 7bytes (8bytes)
For SD, Information field length is 30 + 11bytes (12bytes)
with this specification, I do code as below.
For Rx, I use interrupt drived method, and for Tx just polling
method used.
Now, this code works on only Rx. Tx does not work, which means master
could not get data.
I can receive data, but can not send(Tx) to master device.
Could you please check this procedure in c lang with any advice?
I hope I may get some helpful hands from your side.
---------code in c lang: Main
function-------------------------------------
void main(void){
__disable_interrupt(); //All interrupt disable
SETBIT(INTACK); //NO interrupt ack.
z85c30_set(); //sub-function will be shown below
z85c_enable(); //sub-function will be shown below
__enable_interrupt(); //All interrupt enable
while(1){
switch(sdlcstep){
case 0: //Rx start
Write_reg(5,0x60); //Tx 8bits, Tx disable
Write_reg(3,0xcc); //Rx 8bits, Rx CRC enable, Address
search mode
Write_reg(3,0xcd); //Rx enable
Write_Reg(1,0x10); //Rx int on all received character
or special condition
break;
case 1: //If Rx Ok.
if(RxOk){
for(icnt=4;icnt<=10;icnt++)sdlcRdata[icnt]=sdlcRbuf
[icnt];//READ DATA
RxOk = 0;
for(i=0;i<=15;i++)Txbuffer[i] = Txdata[i]; //input
data to
write
sdlcStep++;
}
break;
case 2: //Rx disable & Tx Start
Write_Reg(3,0xcc);//disable rx
Write_Reg(1,0x00);//disable rx int
Write_Reg(0,0x80); //reset txgenerator
Write_Reg(5,0x69); //Tx 8bit-char,Tx Crc ena, Tx ena
Write_Reg(10,0xa0); //set preset + nrzi
sdlcStep++;
break;
case 3: //write tx data to tx buffer if it is empty.
if(read_reg(0)&0x04){//if Tx buffer empty
Write_Data(sdlcTbuf[tx_data_cnt]);
tx_data_cnt++;
f(tx_data_cnt >= 15) sdlcStep++;
}
break;
case 4: //EOF to append CRC to frame
if(read_reg(0)&0x40){
Write_Reg(0,0xc0);//EOM & CRC Gen; Reset Tx
Underrun/EOM Latch
sdlcStep++;
}
break;
case 5: //Tx disable & Rx ready
Write_Reg(5, 0x60); //TX disable
Write_Reg(9,0x80); //Ch A reset
delay(10); //about 5-clks of PCLK.
Write_Reg(9, 0x0a); //DONE: MIE, NV
sdlcStep =0; //GO to first case 0
break;
}// switch~ case
}//while
}//main
---------code in c lang: Main
function------------------------------------
---------code in c lang: Sub-function called by main
function--------------
void z85c30_set(void)
{
Write_Reg(9, 0xc0); //DONE: Force H/W reset
delay(20);
Write_Reg(4, 0xa0); //DONE: x32 clk, SDLC mode
Write_Reg(3, 0xC0); //DONE: Rx,-8bit/character
Write_Reg(5, 0x60); //DONE: Tx,-8bit/character
Write_Reg(6, 0x70); //DONE: Address(Lower)
Write_Reg(7, 0x7e); //DONE: SDLC SYNC (01111110 sdlc)
//Write_Reg(9, 0x00); //No reset(null command)
Write_Reg(10, 0x20); //DONE: CRC Preset=0, NRZI mode
Write_Reg(14, 0x60); //DONE: DPLL,BRG Disable
Write_Reg(11, 0x70); //DONE: CLK SOURCE CONTROL Rx CLK:
DPLL out, Tx CLK:BRG output
/****TC Table at 4.9152Mhz,condition
----------------------------------------------------
clock factor TC(38400bps)
---------------------------------------------------
1 0x3e(62)
16 0x02(2)
32 0x00(0)
64 -2
********************************************/
Write_Reg(12, 0x00); //DONE: BRG TC low
Write_Reg(13, 0x00); //DONE: BRG TC High
}
void z85c30_enable(void)
{
Write_Reg(14, 0x80); //DONE: DPLL source <-BRG Output(Rx
clock)
Write_Reg(14, 0x03); //DONE: NULL CMD(NO effect), BRG enable,
BRG source: PCLK input
Write_Reg(14, 0xe3); //DONE: BRG enable, DPLL:SET NRZI
Write_Reg(14, 0x23); //DONE: BRG enable
//search mode:DPLL starts to search first
edge of data in
Write_Reg(15,0x01); //WR7' : enable
Write_Reg(7,0x20); //0x23 : Receive 2-nd byte of CRC
Write_Reg(15,0x40); //Tx underrun/EOM interrupt enable
Write_Reg(9, 0x0a); //DONE: MIE, NV
}
---------code in c lang: Sub-function called by main
function-------------
---------code in c lang: Rx interrupt service
routine---------------------
__interrupt void int_RxISR(void)
{
int i;
unsigned char nCmdCode;
unsigned char nData;
CLEARBIT(PORTB,6);//INTACK active low for daisy-chain
for(i=0;i<9;i++){
nCmdCode = read_reg(0x03);
if(nCmdCode&0x20){ //Rx Ip occurs
nData = read_data();//Read Rx buffer
sdlcRbuf[RxPos++] = nData; //read FIFO data from z85c30 data
register
switch(RxPos){ //by buffer position
case 1:
if(sdlcRbuf[0] != 0x70) RxPos = 0; //check first
lower address
break;
case 2:
if(sdlcRbuf[1] != 0x05) RxPos = 0; //check higher
adderss
break;
default:
if(RxPos > 12){ //read till CRC 2bytes
RxPos=0; RxOk =1; i=8;}
break;
} //switch~case
} //if RR3 ip
} //for
} //ISR routine
---------code in c lang: Rx interrupt service
routine---------------------