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
