Clock and SCI problems of mpc5554

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Clock and SCI problems of mpc5554

1,375件の閲覧回数
韦恩
Contributor I

Hi to everyone:

In using the 5554 development board, I encountered two strange problems.
1. I wrote a delay function as follows:

void delay(unsigned int time)
{
	unsigned int i = 0;
	unsigned int count =  SYS_CLOCK * time ;
	for(i = 0;i< count;i++)
	{
	  ;
	}
}
int main
{	
	/*Initialization */
	......
	while(1)
	{
	   SIU.GPDO[1].R = 0;
	   delay(10);
	   SIU.GPDO[1].R = 1;	
	} 
	return 0
}

where: SYS_CLOCK is the configured system clock frequency.
             time is in μs
No matter what the SYS_CLOCK is, the system clock frequency measured by oscilloscope is correct, but the time of this delay function is incorrect. If “unsigned int count = SYS_CLOCK * time ;” is changed to “unsigned int count = SYS_CLOCK * time / 8 ;”, the delay time is correct.Why does this happen? 

2.I test SCI through the following code:

void SCItest(void)
{
	unsigned int data_len = 0;
	unsigned int send_data[8]= {0xF1,0x05,0x91,0x12,0x13,0x45,0x73,0x24};
	unsigned int len = 5;
	unsigned int receive_data[8]={0};
	
	while(1)
	{	
		
		/*Option 1:A Transfer,B Receive*/
		SciSendBuff(SCI_A_ID,send_data,len);
		SciReadBuff(SCI_B_ID,receive_data,len);
		
		/*Option 2:B Transfer,A Receive*/
		//SciSendBuff(SCI_A_ID,send_data,len);
		//SciReadBuff(SCI_B_ID,receive_data,len);
	}
}

If len is greater than 3, no matter I adopt scheme 1 or scheme 2,  There are only the first and last three numbers in receive_data.
example:if len = 5,receive_data[8] = {0xF1,0x91,0x12,0x13,0,0,0,0}
if len = 6,receive_data[8] = {0xF1,0x12,0x13,0x45,0,0,0,0}
if len = 7,receive_data[8] = {0xF1,0x13,0x45,0x73,0,0,0,0}
This is also the case when adding a delay between SciSendBuff() and SciReadBuff().
I know why SCI can receive the first number, but I don't know why it always receives the last three numbers. 

Best regards.

0 件の賞賛
返信
8 返答(返信)

1,363件の閲覧回数
davidtosenovjan
NXP TechSupport
NXP TechSupport

1) Have you measured CLKOUT/ENGCLK frequency? Don't forget there is also pre-dividers on the way (SIU_ECCR).

To double check I could recommend following calculator:

https://community.nxp.com/t5/MPC5xxx-Knowledge-Base/Excel-MPC55xx-MPC56xx-PLL-Calculator/ta-p/112100...

 

2) In the following document, section 15, you may see example. Check whether you implement polling mechanism the same way:

https://www.nxp.com/docs/en/application-note/AN2865.pdf

 

0 件の賞賛
返信

1,327件の閲覧回数
韦恩
Contributor I

Dear Lukas:

Thank you very much for your answer. I checked the relevant codes with reference to the manual, but I still can't understand the causes of these two phenomena.

1) During the debug process, I set multiple system frequencies such as 80MHZ, 85MHZ, 90MHZ, 95MHZ, 100MHZ, 105MHZ, 110MHZ, 115MHZ and 120MHZ. The PREDIV, MFD and RFD settings in the register are correct(I calculated the test results by hand according to the formula), and I measured the CLKOUT pin with an oscilloscope, and its frequency is just half of the system frequency I set(SIU_ECCR.EBDF = 1).

2)I used the code on an2685 and received the data. However,according to the eSCI Data Register (ESCIx_DR), only 8 bits of data can be received per communication. Because it is the way to receive after sending, there is only the first 8-bit data sent in the ESCIx_DRand other data on the communication line cannot be moved into the register. Why can more than 8 bytes of data be received during debug?

Regards,

Lukas

 

 

0 件の賞賛
返信

1,310件の閲覧回数
韦恩
Contributor I

I'm sorry I forgot to post the code

unsigned char SciReadBuff(unsigned char v_sciID_u8,unsigned char *v_buff_u8,unsigned char v_len_u8)
{
    unsigned char l_count_u8 = 0;
    unsigned char l_maxcount_u8 = v_len_u8 * 2;
    unsigned char l_error_u8 = ERROR;
    unsigned int l_data_u16 = 0;

    if( ( v_sciID_u8 < SCI_PORT_NUM ) && ( NULL != v_buff_u8 ))
    {    	
        for( l_count_u8 = 0; l_count_u8 < v_len_u8 ; l_count_u8++)
        {	
        	l_data_u16 = SciGetChar(v_sciID_u8);
        	if((l_data_u16 & 0xFF00) == SCI_DATA_VALID)
        	{
        		v_buff_u8[l_count_u8] = (unsigned char)(l_data_u16 & 0x00FF);
        		l_error_u8 = SUCCESS;
        	}
        	else
        	{
        		l_count_u8--;
        	}
        	
            l_maxcount_u8--;
            if(l_maxcount_u8)
            {
            	//nodealeith
            }
            else
            {
            	l_error_u8 = ERROR;
            	break;
            }
        }
    }
    else
    {
        // no deal with 
    }
    return l_error_u8;
}
/* *******************************************************************/
/**
 *   SciSendChar
 */
/* *******************************************************************/
void SciSendChar(unsigned char v_sciID_u8,unsigned char v_data_u8)
{
	unsigned char l_cycle_count_u8 = 0;
	while(SciIsTxReady(v_sciID_u8) == ERROR)
	{
		l_cycle_count_u8++;
		if(l_cycle_count_u8 >20)
		{
			return;
		}
		else
		{
			// no deal with 
		}
	}
	if(v_sciID_u8 == SCI_A_ID)
    {   
		ESCI_A.SR.R = 0x80000000;//clear TDRE		
		ESCI_A.DR.B.D = v_data_u8;		
    }
	else if(v_sciID_u8 == SCI_B_ID)
	{
		ESCI_B.SR.R = 0x80000000;//清除TDRE标志位		
		ESCI_B.DR.B.D = v_data_u8;		
	}
	else
	{
		//nodealwith
	}
}
/* *******************************************************************/
/**
 *    SciSendBuff
 */
/* *******************************************************************/
unsigned char SciSendBuff(unsigned char v_sciID_u8,unsigned char *v_buff_u8,unsigned char v_len_u8)
{
    unsigned char l_count1_u8 = 0;
    unsigned char l_send_num_u8 = 0;
    uint32 l_delay_count_u32 = 0;  
    if((v_sciID_u8 >= SCI_PORT_NUM) || ( NULL == v_buff_u8 ))
    {
        return l_send_num_u8;
    }
    else
    {
    	//nodealwith
    }
    
    /*TODO*/
	if(v_sciID_u8 == SCI_A_ID)
	{
		for( l_count1_u8 = 0; l_count1_u8 < v_len_u8; l_count1_u8++)
	    {
            if( OK == SciIsTxReady(v_sciID_u8))
            {   
            	ESCI_A.SR.B.TDRE = 1;//clear TDRE        	
            	ESCI_A.DR.B.D = v_buff_u8[l_count1_u8];
            	l_send_num_u8 ++;
            }
            else
            {
            	l_count1_u8--;
            }
	    }
	    
	    ESCI_A.SR.B.TDRE = 1;//clear TDRE
	    ESCI_A.SR.B.TC = 1;//clear TC	   
	}
	else if(v_sciID_u8 == SCI_B_ID)
	{
		for( l_count1_u8 = 0; l_count1_u8 < v_len_u8; l_count1_u8++)
	    {
	        if( OK == SciIsTxReady(v_sciID_u8))
	        {   
	        	ESCI_B.SR.B.TDRE = 1;//clear TDRE 		
	    		ESCI_B.DR.B.D = v_buff_u8[l_count1_u8];
	    		l_send_num_u8 ++;
	        }
	        else
	        {
	        	l_count1_u8--;	
	        }
	    }
	    
	    ESCI_B.SR.R = 0xC0000000;//clear TDRE TC
	}
	else
	{
		//nodealwith
	}
    return l_send_num_u8;
}

 

0 件の賞賛
返信

1,293件の閲覧回数
davidtosenovjan
NXP TechSupport
NXP TechSupport

1) Anyway it is just estimated time as presented code loop may be affected by memory access time, branch prediction, pipelingm cachign and so on. Such measuring would only make sense in case it is senquence of 'nop' operation executed directly from cache memory.

2) You havent shown SciGetChar. I wonder whether you have a time to finish transfer before you read it.

0 件の賞賛
返信

1,262件の閲覧回数
韦恩
Contributor I

Dear davidtosenovjan

I'm sorry for my negligence. This is my code

unsigned char SciIsRxReady(unsigned char v_sciID_u8)
{
	unsigned char l_Rx_ready_u8 = ERROR;
	if(v_sciID_u8 == SCI_A_ID)
    {
		if( ESCI_A.SR.B.RDRF == SCI_RX_FULL )
		{
			l_Rx_ready_u8 = OK;
		}
		else
		{
			l_Rx_ready_u8 = ERROR;
		}
    }
	else if(v_sciID_u8 == SCI_B_ID)
	{
		if( ESCI_B.SR.B.RDRF == SCI_RX_FULL )
		{
			l_Rx_ready_u8 = OK;
		}
		else
		{
			l_Rx_ready_u8 = ERROR;
		}
	}
	else
	{
		//nodealwith
	}
	return l_Rx_ready_u8;
}

unsigned int SciGetChar(unsigned char v_sciID_u8)
{
	unsigned int l_recv_u16 = SCI_DATA_NOVALID;
	unsigned long l_error_u32 = 0;
	unsigned char l_delaycount_u8 =0;
	
/*	while(SciIsRxReady(v_sciID_u8) == ERROR)
	{
		l_delaycount_u8 ++;
		if(l_delaycount_u8 > 10)
		{
			break;
		}
		else
		{
			//nodealwith
		}
		//timeout
	}
	if(l_delaycount_u8 > 10)
	{
		
	}*/
	if(SciIsRxReady(v_sciID_u8) == ERROR)
	{
		//nodealwith
	}
	else
	{
		//check flag
		l_error_u32 = SciRxFlagCheck(v_sciID_u8);
		if(l_error_u32 == OK)
		{
			if(v_sciID_u8 == SCI_A_ID)
			{   
				l_recv_u16 = ESCI_A.DR.B.D & 0x00FF;
				ESCI_A.SR.R = 0x20000000;//clear RDRF
	   		}
	   		else if(v_sciID_u8 == SCI_B_ID)
			{
				l_recv_u16 = ESCI_B.DR.B.D & 0x00FF;
				ESCI_B.SR.R = 0x20000000;//clear RDRF
			}
			else
			{
				//nodealwith
			}	
		}
		else
		{
			//nodealwith
		}			
		//clear Rx flag
		SciRxAck(v_sciID_u8);
	}
	return l_recv_u16;
}

void SciRxAck(unsigned char v_sciID_u8)
{
   	if(v_sciID_u8 == SCI_A_ID)
    {   
		ESCI_A.SR.R = 0x0F000000;//clear flag
    }
	else if(v_sciID_u8 == SCI_B_ID)
	{
		ESCI_B.SR.R = 0x0F000000;///clear flag
	}
	else
	{
		//nodealwith
	}
}

And the picture is the result of running the routine on AN2685.

20211202195133.jpg

0 件の賞賛
返信

1,241件の閲覧回数
davidtosenovjan
NXP TechSupport
NXP TechSupport

Currently I an not sure whether I understand what the issue is actually. If you run the code without debugging, it does not run properly and with debugging per steps, it works fine, correct?

If AN2865 code works fine, then you apparently some issue with you code. Have you debugged it per every character transmission?

0 件の賞賛
返信

1,234件の閲覧回数
韦恩
Contributor I

Dear davidtosenovjan:

Thank you for your reply.

The code can run normally on the development board, but the received data result is abnormal. I have debugged the transmission of each character.

Running the routine in an2685 shows that "Hello world!" was sent completely, but only the first byte was received, not all bytes were received.
It is correct to run the single character transmission written by myself, but by sending n (n > 4) bytes successively before receiving, the first byte and the last three bytes will always be received.

Regards,

davidtosenovjan:

0 件の賞賛
返信

1,186件の閲覧回数
davidtosenovjan
NXP TechSupport
NXP TechSupport

I certain code portion I see using .B instance for clearing flags, what's wrong.

ESCI_A.SR.B.TDRE = 1;//clear TDRE

Such operation clears all flags in the status register.

Pay attention to section 3.2 of following document

https://www.nxp.com/docs/en/engineering-bulletin/EB758.pdf

 

0 件の賞賛
返信