WIZnet Developer Forum

W6100 IO6Library DMA 사용 문의

안녕하세요
일단 W6100을 처음 써봅니다.
다른 시리즈는 써봤지만 W6100은 처음 접근해봅니다.

아래는 IO6library Git에 올라온 원문입니다.

WIZCHIP N bytes read/write Function : It is not mandatory. : But, If you want to use WIZCHIP for high speed access using a peripheral such as DMA, make it as follows. : Even if you do not, you can use N bytes read/write accesses because it is performed by repeating your 1-byte read/write function.
void your_spi_dma_write_buf(uint8_t* pbuf, iodata_t len)
{
/* HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) */
HAL_SPI_Transmit_DMA(SPI1, pbuf, (uint16_t)len);
}

void your_spi_dma_read_buf(uint8_t* pbuf, iodata_t len)
{
/* HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) */
HAL_SPI_Receive_DMA(SPI1, pbuf, (uint16_t)len);
}

위와 같이 동일하게 코드를 작성하였고 해봤지만 동작을 안합니다.

물론

DMA를 사용하지 않은 일반 SPI모드로는 정상 작동하는 것을 확인하였습니다.

아래는 소스의 W6100에 대한 소스입니다.

혹시 잘못된 점이 있을까요?

void wizchip_enable(void) {

HAL_GPIO_WritePin(W6100_SPI1_CS_GPIO_Port, W6100_SPI1_CS_Pin, GPIO_PIN_RESET);

}

void wizchip_disable(void) {

HAL_GPIO_WritePin(W6100_SPI1_CS_GPIO_Port, W6100_SPI1_CS_Pin, GPIO_PIN_SET);

}

void critical_enter(void)

{

__disable_irq();

}

void critical_exit(void)

{

__enable_irq();

}

/* Read 1 byte thru SPI */

uint8_t spi_read_byte()

{

uint8_t ret;

/*HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t pData, uint16_t Size, uint32_t Timeout)/

HAL_SPI_Receive(&hspi1, &ret, 1, 1000);

return ret;

} /* Write 1 byte thru SPI */

void spi_wite_byte(uint8_t wd)

{ /* HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); */

HAL_SPI_Transmit(&hspi1, &wd, 1, 1000);

}

void spi_dma_write_buf(uint8_t* pbuf, datasize_t len)

{

/* HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) */

HAL_SPI_Transmit_DMA(&hspi1, pbuf, (uint16_t)len);

}

void spi_dma_read_buf(uint8_t* pbuf, datasize_t len)

{

/* HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) */

HAL_SPI_Receive_DMA(&hspi1, pbuf, (uint16_t)len);

}

void IP_OG_F(void)

{

//WIZCHIP Enable/Disable

reg_wizchip_cs_cbfunc(wizchip_enable, wizchip_disable);

//WIZCHIP Critical Section

reg_wizchip_cris_cbfunc(critical_enter, critical_exit);

//WIZCHIP read/write function

//reg_wizchip_spi_cbfunc(spi_read_byte, spi_wite_byte, 0, 0);

// If you made DMA function for readign/writting function, you can register as following

reg_wizchip_spi_cbfunc(0, 0, spi_dma_read_buf, spi_dma_write_buf);

// /* For io6Library Read/Write Test */

// Check WIZCHIP ID value for read test

ctlwizchip(CW_GET_ID,&chip_id); // Check WIZCHIP ID value for read test

ctlwizchip(CW_RESET_PHY, 0);

wizchip_init(bufSize, bufSize);

wiz_NetInfo gWIZNETINFO = { .mac = {0x00,0x08,0xdc,0xff,0xff,0xff},

.ip = {172,16,10,236},

.sn = {255, 255, 0, 0},

.gw = {172, 16, 44, 254},

.dns = {168, 126, 63, 1},

.lla = {0xfe,0x80, 0x00,0x00,

0x00,0x00, 0x00,0x00,

0x02,0x08, 0xdc,0xff,

0xfe,0xff, 0xff,0xff},

.gua={0x20,0x01,0x02,0xb8,

0x00,0x10,0x00,0x01,

0x02,0x08,0xdc,0xff,

0xfe,0xff,0xff,0xff},

.sn6={0xff,0xff,0xff,0xff,

0xff,0xff,0xff,0xff,

0x00,0x00,0x00, 0x00,

0x00,0x00,0x00,0x00},

.gw6={0xfe, 0x80, 0x00,0x00,

0x00,0x00,0x00,0x00,

0x02,0x00, 0x87,0xff,

0xfe,0x08, 0x4c,0x81}

}; // Gateway address

uint8_t syslock = SYS_NET_LOCK;

ctlwizchip(CW_SYS_UNLOCK,&syslock);

wizchip_setnetinfo(&gWIZNETINFO);

wizchip_getnetinfo(&gWIZNETINFO);

cpu_add[0] = gWIZNETINFO.ip[0];

// Check PHY Link Led to turn off and then on

//ctlwizchip(CW_GET_ID, &chip_id);

//ctlwizchip(CW_PHY_RESET, 0);

}

제가 알기에는 SPI init하는 부분에서 DMA를 세팅해줘야하는 부분이 있는걸 알고있습니다.
해당 부분이 DMA로활성화되어있는지 확인해보시길 바랍니다.

SPI Init 부분이라면 어디를 말씀하시는지 모르겠습니다.
IO6Library에 나온 코드 그대로 따라했는데 HAL 드라이버에서 만들어지는 SPI init 함수에서 DMA 활성화하는 게 따로 있는지요? 아니면 IO6Library 안에 SPI Init에 DMA 를 셋팅해주는 곳이 있나요?
DMA는 이미 추가되어있습니다.
혹은 IO6Library에 나온 예시에서

void spi_dma_write_buf(uint8_t* pbuf, datasize_t len)
{
HAL_SPI_Transmit_DMA(&hspi1, pbuf, (uint16_t)len);
}

void spi_dma_read_buf(uint8_t* pbuf, datasize_t len)

{
HAL_SPI_Receive_DMA(&hspi1, pbuf, (uint16_t)len);
}

위와 같이 함수를 HAL에서 제공하는 DMA함수로 셋팅하는게 동작을 하는건지 궁금합니다.

저희가 제공하고 있는 Io6Library는 MCU와 관계되어있는 세팅은 하지 않습니다.
그렇기 때문에, MCU를 컨트롤하는 SPI 모드 같은부분은 SPI 를 세팅하는 함수에서 설정하셔야합니다.

위의 코드는 ST의 HAL코드를 사용할때 HAL_SPI_Receive_DMA,HAL_SPI_Transmit_DMA의 함수를 사용해야하기때문에 한번더 함수로 감싸놓은것입니다.

Io6library에서 MCU 셋팅을 하지 않는 것은 알고 있습니다.

SPI 셋팅은 CubeIDE에서 제공되는 SPI 셋팅말고 다른 셋팅이 있는지요?
기본 SPI 통신으로 하는 것은 잘 됩니다.
uint8_t spi_read_byte()
void spi_wite_byte(uint8_t wd)

위 두개 함수만으로는 정상 동작합니다.

위의 코드는 ST의 HAL코드를 사용할때 HAL_SPI_Receive_DMA,HAL_SPI_Transmit_DMA의 함수를 사용해야하기때문에 한번더 함수로 감싸놓은것입니다

→ 위의 말씀은 저렇게 코드만 작성해도 원래는 정상 동작해야 맞다는 말씀이신가요?

cubemx 모양을 다를수 있지만 실제 SPI 세팅에서 아래와 같이 DMA를 세팅하는 부분이 있습니다.

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.