W7500P SPI관련문의

SPI로 data를 읽는데 Scope로 보는것과 읽어진값이 다릅니다.
Scope로 파형을 읽어보면 0x65가 보입니다. 그러나 uart로 확인해 보면 0x00이보이고 가끔은 0x65가 보일때도 있습니다. 문제가 뭔지 알수가 없습니다.

int main()
{
    uint8_t i;
    /* External Clock */
    CRG_PLL_InputFrequencySelect(CRG_OCLK);
    /* Set Systme init */
    SystemInit();
	GpioInit();
	S_UART_Init(57600);
    UART_StructInit(&UART_InitStructure);
    /* Configure UART0 */
    /* Retarget functions for GNU Tools for ARM Embedded Processors*/
    /* Configure Uart0 Interrupt Enable*/
    S_UART_ITConfig((UART_IT_FLAG_TXI|UART_IT_FLAG_RXI),ENABLE);
    /* NVIC configuration */
    NVIC_ClearPendingIRQ(UART2_IRQn);
    NVIC_EnableIRQ(UART2_IRQn);
  
    /* SysTick_Config */
    SysTick_Config((GetSystemClock()/1000));

    /* Set WZ_100US Register */
    setTIC100US((GetSystemClock()/10000));
    /* SSP0 Init -- SSP Master */ 
    SSP_StructInit(&SSP0_InitStructure);
    SSP0_InitStructure.SSP_SerialClockRate   = 0;				// 0 10 500KHz
    SSP0_InitStructure.SSP_FrameFormat  = SSP_FrameFormat_MO; // Motorora SPI mode
    SSP0_InitStructure.SSP_CPHA         = SSP_CPHA_1Edge; 
    SSP0_InitStructure.SSP_CPOL         = SSP_CPOL_Low; 
    SSP0_InitStructure.SSP_DataSize 	= SSP_DataSize_8b; 
    //SSP0_InitStructure.SSP_SOD 			= SSP_SOD_RESET;
    SSP0_InitStructure.SSP_NSS          = SSP_NSS_Hard;
    SSP0_InitStructure.SSP_Mode         = SSP_Mode_Master;
    SSP0_InitStructure.SSP_BaudRatePrescaler = 40;					// 40  about 500Khz
    SSP_Init(SSP0,&SSP0_InitStructure);    

    i = read_eeprom(0x0005);     // 실제값은 0x65가 있슴(scope로 확인함)
    printf("r\n rd : %x", i);              // 받아서 보면 값이 0x00이나옴 가끔 0x65가보일때도있슴)
}

void spi_out(byte data)
{
	SSP_SendData(SSP0, data);
	while( SSP_GetFlagStatus(SSP0, SSP_FLAG_BSY) );	
}

byte spi_in(void)
{
	byte data;
	uint16_t retry=0;
	
	GPIO_ResetBits(GPIOB, GPIO_Pin_3); 

	SSP_SendData(SSP0, 0xff);
	while( SSP_GetFlagStatus(SSP0, SSP_FLAG_BSY) );	
       // 위 부분이 없으면 읽기도전에 chip select를 끝내고 나옴
	retry = 10;

	while (SSP_GetFlagStatus (SSP0, SSP_FLAG_RNE) == RESET);
   	data = (byte)SSP_ReceiveData(SSP0);
   	GPIO_SetBits(GPIOB, GPIO_Pin_3);     //scope로 data읽는 시점을 보기위한 단자임

    return data;
}

byte read_eeprom(word add)                                      
{  
	byte data;
	_EepCsLo();
	spi_out(EepCmdRD);
	spi_out((byte)(add >> 8));
	spi_out((byte)(add & 0x00ff));
	data = spi_in();
	_EepCsHi();
        
    return data;
}

GPIOB 3번 Pin이 SPI cs 인가요?
sip_in에서는 cs 설정을 해주는데
spi_out에서는 cs 설정이 없네요
확인 해보시기 바랍니다.

답변 감사합니다.
위에 주석에서 설명한 것처럼 spi cs는 다른핀이고여 GPIOB pin3은 data를 읽는 time을 scope로 확인하기위해 임의의 핀을 설정해서 본것입니다.
spi_in()함수에서 SSP_ReceiveData()이 함수가 동작하는 시점을 보기위한것입니다. 확인결과 읽는 시점은 문제없어 보이고여…
현재 쓰는부분 spi wirite는 문제가 없어서 별도 내용을 추가하진 않은것입니다.
spi cs는 read_eeprom()함수에 있는 _EepCsLo();, _EepCsHi(); 이고여 GPIOB pin1입니다.

SSP BaudRate Prescaler 는 2의 승수 값으로만 설정이 가능합니다.
40으로 설정시 정상적인 동작이 보장되지 않습니다.

#define SSP_BaudRatePrescaler_2 ((uint32_t)0x0002)
#define SSP_BaudRatePrescaler_4 ((uint32_t)0x0004)
#define SSP_BaudRatePrescaler_8 ((uint32_t)0x0008)
#define SSP_BaudRatePrescaler_16 ((uint32_t)0x0010)
#define SSP_BaudRatePrescaler_32 ((uint32_t)0x0020)
#define SSP_BaudRatePrescaler_64 ((uint32_t)0x0040)
#define SSP_BaudRatePrescaler_128 ((uint32_t)0x0080)
#define SSP_BaudRatePrescaler_254 ((uint32_t)0x00FE)

define 되어있는 값들이 있으니 해당값으로 수정하시 거나 0x40으로 수정하시길 바랍니다.

위 말씀하신대로 아래처럼 수정하였으나 결과는 같습니다.
SSP0_InitStructure.SSP_BaudRatePrescaler = SSP_BaudRatePrescaler_64;

RS232로 받은 data를 보여드리면
rd : 65r rd : 0r rd : 0r rd : 0r rd : 65r rd : 0r rd : 0r rd : 0r rd : 0r rd : 0r
실제 0x65 값이 있고 scope로 확인해도 0x65가 확인되는데
data = (byte)SSP_ReceiveData(SSP0); 이 SSP_ReceiveData(SSP0) 함수로 읽는 값이 정상이 아닌것이 이유를 모르겠습니다.

while (SSP_GetFlagStatus (SSP0, SSP_FLAG_RNE) == SET) 으로 변경해주셔야할것 같습니다.
RNE flag는 1인 경우가 Receive FIFO에 데이터가 있는경우입니다.

답변감사합니다.
말씀하신대로
while (SSP_GetFlagStatus (SSP0, SSP_FLAG_RNE) == SET):
이렇게 하면 이부분에서 나오지 못하고 무한루프상태입니다.

추가로 말씀드리면 위 spi_in()함수는 W7500P_FW 예제중
SD_Card_LED중 mmc_sd.c에서
uint8_t bsp_readwritebyte_spi1 (uint8_t tx_data)
{
uint16_t retry=0;
/* Loop while DR register in not emplty /
while (SSP_GetFlagStatus (SSP1, SSP_FLAG_TNF) == RESET)
{
retry++;
if(retry>400)
return 0;
}
/
Send byte through the SPI1 peripheral /
SSP_SendData (SSP1, tx_data);
retry=0;
/
Wait to receive a byte */
while (SSP_GetFlagStatus (SSP1, SSP_FLAG_RNE) == RESET)
{
retry++;

	if(retry>400)
		return 0;
}		
/* Return the byte read from the SPI bus */
return SSP_ReceiveData (SSP1);

}
이부분의 예제를 참고한것입니다.