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---------------------
ATmeag128 8Mhz with Z85c30 SCC(zilog)
Started by ●February 25, 2008
Reply by ●February 25, 20082008-02-25
On Mon, 25 Feb 2008 09:41:22 -0600, "sebastiankoo" <sebikoo@naver.com> wrote in comp.arch.embedded:> 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)[snip]> 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.It's been a long time since I programmed a Z85C30, and then it was on a Z80. I think the last time was before AVR architecture even existed. But I do see a problem in your C code...> ---------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;In this case you do not modify the value of "sdlcstep". You don't show the definition or initialization of this variable in the code you posted, but I assume it has external linkage and static storage duration, so it is initialized to 0. The first time into this loop, the value is 0. In the case for the value of 0, you never change the value. So your loop will always execute this case forever. So you never get farther into your state machine, never get to where you try to transmit. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://c-faq.com/ comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html






