STM32G431은 170Mhz로 구동이 되고 SPI는 80Mhz(최대 보장75Mhz) 까지 설정 가능하므로 SPI로 구동되는 W5500모듈의 전송율을 테스트 해 보기에 좋을것 같다.
네트웍 전송율 테스트를 위해 PC에서는 iperf 프로그램을 사용하고 STM32에서는 W5500 TCP loopback 테스트 코를 조금 수정해 iperf 클라이언트 코드로 작성했다.
int32_t iperf_tcps(uint8_t sn, uint8_t* buf, uint16_t port)
{
int32_t ret;
uint16_t size = 0, sentsize=0;
switch(getSn_SR(sn))
{
case SOCK_ESTABLISHED :
if(getSn_IR(sn) & Sn_IR_CON)
{
setSn_IR(sn,Sn_IR_CON);
}
if((size = getSn_RX_RSR(sn)) > 0)
{
if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
#if _USE_DELAY
_delay(_TX_DELAY_TIME);
#endif
ret = recv(sn,buf,size);
if(ret <= 0) return ret;
#if _USE_LOOP_BACK
sentsize = 0;
while(size != sentsize)
{
ret = send(sn,buf+sentsize,size-sentsize);
if(ret < 0)
{
close(sn);
return ret;
}
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
}
#endif
}
break;
case SOCK_CLOSE_WAIT :
if((ret=disconnect(sn)) != SOCK_OK) return ret;
break;
case SOCK_INIT :
if( (ret = listen(sn)) != SOCK_OK) return ret;
break;
case SOCK_CLOSED:
if((ret=socket(sn,Sn_MR_TCP,port,0x00)) != sn)
cnt = 0;
return ret;
break;
default:
break;
}
return 1;
}
170Mhz 클럭에서 21.25Mhz SPI클럭으로 테스트 해보자
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8
STM32G431의 SPI클럭을 높혀 보자
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2
로 85Mhz로 구동하면 에러가 많이 발생한다.
메인 클럭을 122Mhz로 설정하면 SPI클럭을 62.1Mhz로 설정 할 수 있다.
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;
RCC_OscInitStruct.PLL.PLLN = 61;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
}
62.1Mhz SPI 클럭에서 전송율은 더 낮아진다. 메인 클럭이 줄어서 그런가?
DMA를 사용하지 않을 경우 W5500의 상태값을 읽어 올경우 SPI 클럭 파형이다.
STM32G4 SPI DMA 테스트 예제를 이용하여 테스트 해 보자.
DMA를 사용하여 W5500의 상태값을 읽을 때 SPI 클럭 파형으로 지연시간이 거의 없는것을 확인 할 수 있다.
W5500의 FIFO 메모리를 최대로 키우고 SPI DMA를 사용하여 STM32G431에서 W5500 iperf TCP 전송율 테스트 결과 26Mbps로 측정이 된다.
TCP loopback 테스트로 송수신 통신을 구현하면 13Mbps 로 측정이 된다.