Hi @lawrence ,
This is helpful thanks, I am developing for nucleo 446re using mbed studio so can you help me how can i enable dma mode for spi for my setup and hardware. i have attached my code which i tried for dma mode can you look through it if that helps. Thanks a lot
code -
#include “mbed.h”
#include “w5500_spi.h”
#include “socket.h”
#include “header”
#define WIZCHIP W5500
#define WIZCHIP_IO_MODE WIZCHIP_IO_MODE_SPI_VDM
#define WAIT_TIME 1000 // msec
#define BUFFERLENGTH 12000
#define SOCKET_N 1
DigitalOut led1(LED1);
SPI spi1(D11, D12, D13);
DigitalOut cs(D10);
DigitalOut rst(D4);
DigitalOut toggle(D14);
wiz_NetInfo net_info = {
.mac = {0x00, 0x08, 0xdc, 0xab, 0xcd, 0xef},
.ip = {192, 168, 1, 15},
.sn = {255, 255, 255, 0},
.gw = {192, 168, 1, 1},
.dns = {8, 8, 8, 8},
.dhcp = NETINFO_STATIC
};
wiz_PhyConf phyConf = {
.by = PHY_CONFBY_SW,
.mode = PHY_MODE_MANUAL,
.speed = PHY_SPEED_100,
.duplex = PHY_DUPLEX_FULL,
};
char buf[BUFFERLENGTH] = {0};
// DMA Configurations
#define DMA_CHANNEL_RX 2 // Define the DMA channel for SPI RX
#define DMA_CHANNEL_TX 3 // Define the DMA channel for SPI TX
#define DMA_TX_FLAG DMA_FLAG_TC_2 // Define the DMA TX flag
#define DMA_RX_FLAG DMA_FLAG_TC_3 // Define the DMA RX flag
DMA_HandleTypeDef hdma_rx;
DMA_HandleTypeDef hdma_tx;
void spiReadBurst(uint8_t* pBuf, uint16_t len) {
hdma_tx.Instance = DMA_INSTANCE_SPI_TX; // Set the DMA instance for SPI TX
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_rx.Instance = ...; // Set the DMA instance for SPI RX
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode = DMA_NORMAL;
hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_tx);
HAL_DMA_Init(&hdma_rx);
/* Enable SPI Rx/Tx DMA Request */
__HAL_SPI_ENABLE_DMA(&spi1, SPI_DMA_TX);
__HAL_SPI_ENABLE_DMA(&spi1, SPI_DMA_RX);
/* Configure the DMA TX channel */
HAL_DMA_Start(&hdma_tx, (uint32_t)pBuf, (uint32_t)&spi1.Instance->DR, len);
/* Configure the DMA RX channel */
HAL_DMA_Start(&hdma_rx, (uint32_t)&spi1.Instance->DR, (uint32_t)pBuf, len);
/* Wait for the end of Data Transfer */
HAL_DMA_PollForTransfer(&hdma_tx, HAL_DMA_FULL_TRANSFER, 1000);
HAL_DMA_PollForTransfer(&hdma_rx, HAL_DMA_FULL_TRANSFER, 1000);
/* Disable SPI Rx/Tx DMA Request */
__HAL_SPI_DISABLE_DMA(&spi1, SPI_DMA_TX);
__HAL_SPI_DISABLE_DMA(&spi1, SPI_DMA_RX);
/* Clear the DMA transfer complete flags */
__HAL_DMA_CLEAR_FLAG(&hdma_tx, DMA_TX_FLAG);
__HAL_DMA_CLEAR_FLAG(&hdma_rx, DMA_RX_FLAG);
HAL_DMA_DeInit(&hdma_tx);
HAL_DMA_DeInit(&hdma_rx);
}
int main() {
spi1.format(8, 0);
spi1.frequency(33000000);
w5500Init(&spi1, &cs, &rst);
printf("W5500 initialized\n\r");
int8_t err;
if (ctlwizchip(CW_SET_PHYCONF, (void*) &phyConf) == -1) {
printf("Failed to set phyconf\n\r");
return -1;
}
printf("PHY configuration set\n\r");
if (ctlnetwork(CN_SET_NETINFO, (void*) &net_info) == -1) {
printf("Failed to set netinfo\n\r");
return -1;
}
printf("Network info set\n\r");
wiz_PhyConf currentStatus;
ctlwizchip(CW_GET_PHYSTATUS, (void*) ¤tStatus);
printf("Speed is %d Mb/s. ", currentStatus.speed == PHY_SPEED_100 ? 100 : 10);
printf("%s.\n\r", currentStatus.duplex == PHY_DUPLEX_FULL ? "Full Duplex" : "Half Duplex");
err = socket(SOCKET_N, Sn_MR_TCP, 1234, SF_TCP_NODELAY);
if (err != SOCK_OK) {
printf("Failed to open socket. Error %d\n\r", err);
return -1;
}
printf("Socket opened\n\r");
err = listen(SOCKET_N);
if (err != SOCK_OK) {
printf("Failed to listen/accept socket. Error %d\n\r", err);
return -1;
}
printf("Listening for connection...\n\r");
uint8_t sock_state = 0;
while (sock_state != SOCK_ESTABLISHED) {
getsockopt(SOCKET_N, SO_STATUS, (void*) &sock_state);
printf("Sock State is: %d\n\r", sock_state);
thread_sleep_for(WAIT_TIME);
}
printf("Connection established\n\r");
Timer t;
while (true) {
for (int i = 0; i < BUFFERLENGTH-1; i++) {
buf[i] = 'A' + (i % 26);
}
buf[BUFFERLENGTH-1] = '\0';
t.reset();
t.start();
toggle.write(1);
spiReadBurst((uint8_t*) buf, strlen(buf));
toggle.write(0);
t.stop();
float elapsed_time = t.read();
int num_bytes_transmitted = strlen(buf);
float transfer_speed = (num_bytes_transmitted / elapsed_time) * 8 / 1000000.0f;
printf("Sent %d bytes in %.6f seconds, transfer speed: %.8f Mbps\n", num_bytes_transmitted, elapsed_time, transfer_speed);
memset(buf, 0, BUFFERLENGTH);
printf("Buffer cleared\n\r");
led1 = !led1;
printf("LED toggled\n\r");
thread_sleep_for(1000);
}
}