Skip to content

Commit ba5711a

Browse files
committed
stm32/eth: Move DMA TX/RX index variables to normal RAM.
RAM shared with DMA needs caching disabled, which is slower for the MCU to access. So move these index variables (which are not shared with DMA) to normal RAM. Signed-off-by: Damien George <[email protected]>
1 parent 3202d57 commit ba5711a

File tree

1 file changed

+26
-23
lines changed

1 file changed

+26
-23
lines changed

ports/stm32/eth.c

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,12 @@ typedef struct _eth_dma_t {
133133
eth_dma_tx_descr_t tx_descr[TX_BUF_NUM];
134134
uint8_t rx_buf[RX_BUF_NUM * RX_BUF_SIZE] __attribute__((aligned(8)));
135135
uint8_t tx_buf[TX_BUF_NUM * TX_BUF_SIZE] __attribute__((aligned(8)));
136-
size_t rx_descr_idx;
137-
size_t tx_descr_idx;
138136
// Make sure the size of this struct is 16k, for the MPU.
139137
uint8_t padding[16 * 1024
140138
- sizeof(eth_dma_rx_descr_t) * RX_BUF_NUM
141139
- sizeof(eth_dma_tx_descr_t) * TX_BUF_NUM
142140
- RX_BUF_NUM * RX_BUF_SIZE
143-
- TX_BUF_NUM * TX_BUF_SIZE
144-
- sizeof(size_t) * 2];
141+
- TX_BUF_NUM * TX_BUF_SIZE];
145142
} eth_dma_t;
146143

147144
typedef struct _eth_t {
@@ -153,8 +150,14 @@ typedef struct _eth_t {
153150
int16_t (*phy_get_link_status)(uint32_t phy_addr);
154151
} eth_t;
155152

153+
// This struct contains RX and TX buffers shared with the DMA, and they may need
154+
// to go in a special RAM section, or have MPU settings applied.
156155
static eth_dma_t eth_dma MICROPY_HW_ETH_DMA_ATTRIBUTE;
157156

157+
// These variables index the buffers in eth_dma and are not shared with DMA.
158+
static size_t eth_dma_rx_descr_idx;
159+
static size_t eth_dma_tx_descr_idx;
160+
158161
eth_t eth_instance;
159162

160163
static void eth_mac_deinit(eth_t *self);
@@ -554,7 +557,7 @@ static int eth_mac_init(eth_t *self) {
554557
#else
555558
ETH->DMARDLAR = (uint32_t)&eth_dma.rx_descr[0];
556559
#endif
557-
eth_dma.rx_descr_idx = 0;
560+
eth_dma_rx_descr_idx = 0;
558561

559562
// Configure TX descriptor lists
560563
for (size_t i = 0; i < TX_BUF_NUM; ++i) {
@@ -585,7 +588,7 @@ static int eth_mac_init(eth_t *self) {
585588
#else
586589
ETH->DMATDLAR = (uint32_t)&eth_dma.tx_descr[0];
587590
#endif
588-
eth_dma.tx_descr_idx = 0;
591+
eth_dma_tx_descr_idx = 0;
589592

590593
// Configure DMA
591594
#if defined(STM32H5) || defined(STM32H7)
@@ -730,7 +733,7 @@ static int eth_tx_buf_get(size_t len, uint8_t **buf) {
730733
}
731734

732735
// Wait for DMA to release the current TX descriptor (if it has it)
733-
eth_dma_tx_descr_t *tx_descr = &eth_dma.tx_descr[eth_dma.tx_descr_idx];
736+
eth_dma_tx_descr_t *tx_descr = &eth_dma.tx_descr[eth_dma_tx_descr_idx];
734737
uint32_t t0 = mp_hal_ticks_ms();
735738
for (;;) {
736739
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
@@ -749,24 +752,24 @@ static int eth_tx_buf_get(size_t len, uint8_t **buf) {
749752

750753
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
751754
// Update TX descriptor with length and buffer pointer
752-
*buf = &eth_dma.tx_buf[eth_dma.tx_descr_idx * TX_BUF_SIZE];
755+
*buf = &eth_dma.tx_buf[eth_dma_tx_descr_idx * TX_BUF_SIZE];
753756
tx_descr->tdes2 = len & TX_DESCR_2_B1L_Msk;
754757
tx_descr->tdes0 = (uint32_t)*buf;
755758
#else
756759
// Update TX descriptor with length, buffer pointer and linked list pointer
757-
*buf = &eth_dma.tx_buf[eth_dma.tx_descr_idx * TX_BUF_SIZE];
760+
*buf = &eth_dma.tx_buf[eth_dma_tx_descr_idx * TX_BUF_SIZE];
758761
tx_descr->tdes1 = len << TX_DESCR_1_TBS1_Pos;
759762
tx_descr->tdes2 = (uint32_t)*buf;
760-
tx_descr->tdes3 = (uint32_t)&eth_dma.tx_descr[(eth_dma.tx_descr_idx + 1) % TX_BUF_NUM];
763+
tx_descr->tdes3 = (uint32_t)&eth_dma.tx_descr[(eth_dma_tx_descr_idx + 1) % TX_BUF_NUM];
761764
#endif
762765

763766
return 0;
764767
}
765768

766769
static int eth_tx_buf_send(void) {
767770
// Get TX descriptor and move to next one
768-
eth_dma_tx_descr_t *tx_descr = &eth_dma.tx_descr[eth_dma.tx_descr_idx];
769-
eth_dma.tx_descr_idx = (eth_dma.tx_descr_idx + 1) % TX_BUF_NUM;
771+
eth_dma_tx_descr_t *tx_descr = &eth_dma.tx_descr[eth_dma_tx_descr_idx];
772+
eth_dma_tx_descr_idx = (eth_dma_tx_descr_idx + 1) % TX_BUF_NUM;
770773

771774
// Schedule to send next outgoing frame
772775
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
@@ -792,12 +795,12 @@ static int eth_tx_buf_send(void) {
792795
if (ETH->DMACSR & ETH_DMACSR_TBU) {
793796
ETH->DMACSR = ETH_DMACSR_TBU;
794797
}
795-
ETH->DMACTDTPR = (uint32_t)&eth_dma.tx_descr[eth_dma.tx_descr_idx];
798+
ETH->DMACTDTPR = (uint32_t)&eth_dma.tx_descr[eth_dma_tx_descr_idx];
796799
#elif defined(STM32N6)
797800
if (ETH->DMA_CH[TX_DMA_CH].DMACSR & ETH_DMACxSR_TBU) {
798801
ETH->DMA_CH[TX_DMA_CH].DMACSR = ETH_DMACxSR_TBU;
799802
}
800-
ETH->DMA_CH[TX_DMA_CH].DMACTXDTPR = (uint32_t)&eth_dma.tx_descr[eth_dma.tx_descr_idx];
803+
ETH->DMA_CH[TX_DMA_CH].DMACTXDTPR = (uint32_t)&eth_dma.tx_descr[eth_dma_tx_descr_idx];
801804
#else
802805
if (ETH->DMASR & ETH_DMASR_TBUS) {
803806
ETH->DMASR = ETH_DMASR_TBUS;
@@ -810,9 +813,9 @@ static int eth_tx_buf_send(void) {
810813

811814
static void eth_dma_rx_free(void) {
812815
// Get RX descriptor, RX buffer and move to next one
813-
eth_dma_rx_descr_t *rx_descr = &eth_dma.rx_descr[eth_dma.rx_descr_idx];
814-
uint8_t *buf = &eth_dma.rx_buf[eth_dma.rx_descr_idx * RX_BUF_SIZE];
815-
eth_dma.rx_descr_idx = (eth_dma.rx_descr_idx + 1) % RX_BUF_NUM;
816+
eth_dma_rx_descr_t *rx_descr = &eth_dma.rx_descr[eth_dma_rx_descr_idx];
817+
uint8_t *buf = &eth_dma.rx_buf[eth_dma_rx_descr_idx * RX_BUF_SIZE];
818+
eth_dma_rx_descr_idx = (eth_dma_rx_descr_idx + 1) % RX_BUF_NUM;
816819

817820
// Schedule to get next incoming frame
818821
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
@@ -826,16 +829,16 @@ static void eth_dma_rx_free(void) {
826829
| RX_BUF_SIZE << RX_DESCR_1_RBS1_Pos // maximum buffer length
827830
;
828831
rx_descr->rdes2 = (uint32_t)buf;
829-
rx_descr->rdes3 = (uint32_t)&eth_dma.rx_descr[eth_dma.rx_descr_idx];
832+
rx_descr->rdes3 = (uint32_t)&eth_dma.rx_descr[eth_dma_rx_descr_idx];
830833
rx_descr->rdes0 = 1 << RX_DESCR_0_OWN_Pos; // owned by DMA
831834
#endif
832835

833836
// Notify ETH DMA that there is a new RX descriptor available
834837
__DMB();
835838
#if defined(STM32H5) || defined(STM32H7)
836-
ETH->DMACRDTPR = (uint32_t)&rx_descr[eth_dma.rx_descr_idx];
839+
ETH->DMACRDTPR = (uint32_t)&rx_descr[eth_dma_rx_descr_idx];
837840
#elif defined(STM32N6)
838-
ETH->DMA_CH[RX_DMA_CH].DMACRXDTPR = (uint32_t)&rx_descr[eth_dma.rx_descr_idx];
841+
ETH->DMA_CH[RX_DMA_CH].DMACRXDTPR = (uint32_t)&rx_descr[eth_dma_rx_descr_idx];
839842
#else
840843
ETH->DMARPDR = 0;
841844
#endif
@@ -867,13 +870,13 @@ void ETH_IRQHandler(void) {
867870
#endif
868871
for (;;) {
869872
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
870-
eth_dma_rx_descr_t *rx_descr_l = &eth_dma.rx_descr[eth_dma.rx_descr_idx];
873+
eth_dma_rx_descr_t *rx_descr_l = &eth_dma.rx_descr[eth_dma_rx_descr_idx];
871874
if (rx_descr_l->rdes3 & (1 << RX_DESCR_3_OWN_Pos)) {
872875
// No more RX descriptors ready to read
873876
break;
874877
}
875878
#else
876-
eth_dma_rx_descr_t *rx_descr = &eth_dma.rx_descr[eth_dma.rx_descr_idx];
879+
eth_dma_rx_descr_t *rx_descr = &eth_dma.rx_descr[eth_dma_rx_descr_idx];
877880
if (rx_descr->rdes0 & (1 << RX_DESCR_0_OWN_Pos)) {
878881
// No more RX descriptors ready to read
879882
break;
@@ -888,7 +891,7 @@ void ETH_IRQHandler(void) {
888891
#endif
889892
len -= 4; // discard CRC at end
890893
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
891-
uint8_t *buf = &eth_dma.rx_buf[eth_dma.rx_descr_idx * RX_BUF_SIZE];
894+
uint8_t *buf = &eth_dma.rx_buf[eth_dma_rx_descr_idx * RX_BUF_SIZE];
892895
#else
893896
uint8_t *buf = (uint8_t *)rx_descr->rdes2;
894897
#endif

0 commit comments

Comments
 (0)