fix: spi dma
Squashed commit of the following: commit f0df85e2d18ff36b04443ddb23e645cbbd5bfa58 Author: kuwoyuki <kuwoyuki@cock.li> Date: Wed Oct 16 01:36:26 2024 +0600 fix: SPI DMA wait for SPI TXE and BSY flags, also fix korean lib commit a16b9f769807a78803ba1d7cd10a4a4843827bb2 Author: kuwoyuki <kuwoyuki@cock.li> Date: Tue Oct 15 21:09:59 2024 +0600 moar log commit 0c457e17ffb956cb5fbbc40865e62f8acf8f2eea Author: kuwoyuki <kuwoyuki@cock.li> Date: Tue Oct 15 14:09:31 2024 +0600 _ commit a0b6820bc1312e429d04bf0bb39bc2a8b234cfc5 Author: kuwoyuki <kuwoyuki@cock.li> Date: Tue Oct 15 13:55:24 2024 +0600 rewrite w/o interrupts commit 83c2ab75b326be098bc15698d77ab650b14613e0 Author: kuwoyuki <kuwoyuki@cock.li> Date: Tue Oct 15 13:01:41 2024 +0600 dma config commit d871fef77d7c1838ac84f02a499f5555f78bc9ce Author: kuwoyuki <kuwoyuki@cock.li> Date: Tue Oct 15 04:47:23 2024 +0600 more dma
This commit is contained in:
11
README.md
11
README.md
@@ -12,9 +12,16 @@ fw for a ch32v203 node w/ w5500 ethernet
|
|||||||
- SPI DMA only works with [prescalers](https://git.hye.su/mira/ch32-node/src/branch/master/src/spi_dma.c#L140) 8 and 64?
|
- SPI DMA only works with [prescalers](https://git.hye.su/mira/ch32-node/src/branch/master/src/spi_dma.c#L140) 8 and 64?
|
||||||
- Also, for some reason it needs a ~50ms delay before configuring w5500 when compiled **with** `-O0`, not needed with `-Os`...
|
- Also, for some reason it needs a ~50ms delay before configuring w5500 when compiled **with** `-O0`, not needed with `-Os`...
|
||||||
|
|
||||||
Not an interrupt priority issue?:
|
## Diff between SPI w/ and w/o DMA:
|
||||||

|
### SPI DMA
|
||||||
|

|
||||||
|

|
||||||
|
### SPI
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
00 09 04 C0 A8 66 01 02
|
||||||
|
00 09 04 C0 A8 66 01 02 02
|
||||||
|
|
||||||
## ~~previous (DNS Processing)~~
|
## ~~previous (DNS Processing)~~
|
||||||
solved by [patching](https://git.hye.su/mira/ch32-node/commit/259d63197e06c1a92b979490d4cd8f0fdb98f8d0#diff-6ba50689ba55dac7cfe3e9b011e594098c931e21) the korean bloatlib (`dns_makequery` in DNS.c)
|
solved by [patching](https://git.hye.su/mira/ch32-node/commit/259d63197e06c1a92b979490d4cd8f0fdb98f8d0#diff-6ba50689ba55dac7cfe3e9b011e594098c931e21) the korean bloatlib (`dns_makequery` in DNS.c)
|
||||||
|
|||||||
@@ -85,7 +85,11 @@ uint8_t WIZCHIP_READ(uint32_t AddrSel)
|
|||||||
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
|
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
|
||||||
WIZCHIP.IF.SPI._write_burst(spi_data, 3);
|
WIZCHIP.IF.SPI._write_burst(spi_data, 3);
|
||||||
}
|
}
|
||||||
|
if (WIZCHIP.IF.SPI._read_burst) {
|
||||||
|
WIZCHIP.IF.SPI._read_burst(&ret, 1);
|
||||||
|
} else {
|
||||||
ret = WIZCHIP.IF.SPI._read_byte();
|
ret = WIZCHIP.IF.SPI._read_byte();
|
||||||
|
}
|
||||||
|
|
||||||
WIZCHIP.CS._deselect();
|
WIZCHIP.CS._deselect();
|
||||||
WIZCHIP_CRITICAL_EXIT();
|
WIZCHIP_CRITICAL_EXIT();
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
//
|
//
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
//M20150401 : Typing Error
|
//M20150401 : Typing Error
|
||||||
//#define SOCK_ANY_PORT_NUM 0xC000;
|
//#define SOCK_ANY_PORT_NUM 0xC000;
|
||||||
@@ -507,6 +508,7 @@ int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t
|
|||||||
return SOCKERR_SOCKMODE;
|
return SOCKERR_SOCKMODE;
|
||||||
}
|
}
|
||||||
CHECK_SOCKDATA();
|
CHECK_SOCKDATA();
|
||||||
|
|
||||||
//M20140501 : For avoiding fatal error on memory align mismatched
|
//M20140501 : For avoiding fatal error on memory align mismatched
|
||||||
//if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
|
//if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
|
||||||
//{
|
//{
|
||||||
@@ -518,11 +520,17 @@ int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t
|
|||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
|
//if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
|
||||||
if((taddr == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_IPINVALID;
|
if((taddr == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) {
|
||||||
if((port == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_PORTZERO;
|
return SOCKERR_IPINVALID;
|
||||||
|
}
|
||||||
|
if((port == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) {
|
||||||
|
return SOCKERR_PORTZERO;
|
||||||
|
}
|
||||||
tmp = getSn_SR(sn);
|
tmp = getSn_SR(sn);
|
||||||
//#if ( _WIZCHIP_ < 5200 )
|
//#if ( _WIZCHIP_ < 5200 )
|
||||||
if((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) return SOCKERR_SOCKSTATUS;
|
if((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) {
|
||||||
|
return SOCKERR_SOCKSTATUS;
|
||||||
|
}
|
||||||
//#else
|
//#else
|
||||||
// if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
|
// if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
|
||||||
//#endif
|
//#endif
|
||||||
@@ -530,12 +538,19 @@ int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t
|
|||||||
setSn_DIPR(sn,addr);
|
setSn_DIPR(sn,addr);
|
||||||
setSn_DPORT(sn,port);
|
setSn_DPORT(sn,port);
|
||||||
freesize = getSn_TxMAX(sn);
|
freesize = getSn_TxMAX(sn);
|
||||||
if (len > freesize) len = freesize; // check size not to exceed MAX size.
|
if (len > freesize) {
|
||||||
|
len = freesize; // check size not to exceed MAX size.
|
||||||
|
}
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
freesize = getSn_TX_FSR(sn);
|
freesize = getSn_TX_FSR(sn);
|
||||||
if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
|
if(getSn_SR(sn) == SOCK_CLOSED) {
|
||||||
if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
|
return SOCKERR_SOCKCLOSED;
|
||||||
|
}
|
||||||
|
if( (sock_io_mode & (1<<sn)) && (len > freesize) ) {
|
||||||
|
return SOCK_BUSY;
|
||||||
|
}
|
||||||
if(len <= freesize) break;
|
if(len <= freesize) break;
|
||||||
};
|
};
|
||||||
wiz_send_data(sn, buf, len);
|
wiz_send_data(sn, buf, len);
|
||||||
@@ -558,6 +573,7 @@ int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t
|
|||||||
setSn_CR(sn,Sn_CR_SEND);
|
setSn_CR(sn,Sn_CR_SEND);
|
||||||
/* wait to process the command... */
|
/* wait to process the command... */
|
||||||
while(getSn_CR(sn));
|
while(getSn_CR(sn));
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
tmp = getSn_IR(sn);
|
tmp = getSn_IR(sn);
|
||||||
@@ -586,6 +602,7 @@ int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t
|
|||||||
#endif
|
#endif
|
||||||
//M20150409 : Explicit Type Casting
|
//M20150409 : Explicit Type Casting
|
||||||
//return len;
|
//return len;
|
||||||
|
|
||||||
return (int32_t)len;
|
return (int32_t)len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
notes/SPI_1.png
Normal file
BIN
notes/SPI_1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 164 KiB |
BIN
notes/SPI_2.png
Normal file
BIN
notes/SPI_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
BIN
notes/SPI_DMA_no_irq_1.png
Normal file
BIN
notes/SPI_DMA_no_irq_1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
BIN
notes/SPI_DMA_no_irq_2.png
Normal file
BIN
notes/SPI_DMA_no_irq_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
24
src/main.c
24
src/main.c
@@ -47,23 +47,23 @@ void message_arrived(MessageData* md) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_binary(uint32_t value) {
|
// void print_bin(uint32_t value) {
|
||||||
for (int i = 31; i >= 0; i--) {
|
// for (int i = 31; i >= 0; i--) {
|
||||||
DEBUG_PRINT("%d", (value >> i) & 1);
|
// DEBUG_PRINT("%d", (value >> i) & 1);
|
||||||
if (i % 4 == 0) printf(" "); // Add space for readability
|
// if (i % 4 == 0) printf(" ");
|
||||||
}
|
// }
|
||||||
DEBUG_PRINT("\n");
|
// DEBUG_PRINT("\n");
|
||||||
}
|
// }
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
init_system();
|
init_system();
|
||||||
Delay_Ms(55);
|
Delay_Ms(55);
|
||||||
|
|
||||||
uint32_t intsyscr = __get_INTSYSCR();
|
// uint32_t intsyscr = __get_INTSYSCR();
|
||||||
DEBUG_PRINT("INTSYSCR Register Configuration:\n");
|
// DEBUG_PRINT("INTSYSCR:\n");
|
||||||
DEBUG_PRINT("Hexadecimal: 0x%08X\n", intsyscr);
|
// DEBUG_PRINT("hex: 0x%08X\n", intsyscr);
|
||||||
DEBUG_PRINT("Binary: ");
|
// DEBUG_PRINT("bin: ");
|
||||||
print_binary(intsyscr);
|
// print_binary(intsyscr);
|
||||||
|
|
||||||
// DEBUG_PRINT("init_system() done\n");
|
// DEBUG_PRINT("init_system() done\n");
|
||||||
configure_network();
|
configure_network();
|
||||||
|
|||||||
189
src/spi_dma.c
189
src/spi_dma.c
@@ -3,103 +3,11 @@
|
|||||||
#include "ch32v003fun.h"
|
#include "ch32v003fun.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
volatile transfer_state_t tx_state = IDLE;
|
#define RX_Channel DMA1_Channel2
|
||||||
volatile transfer_state_t rx_state = IDLE;
|
#define TX_Channel DMA1_Channel3
|
||||||
|
|
||||||
static const uint8_t tx_dummy_byte = 0xFF;
|
static const uint8_t tx_dummy_byte = 0xFF;
|
||||||
static uint8_t rx_dummy; // Static RX dummy buffer
|
static uint8_t rx_dummy;
|
||||||
|
|
||||||
static inline void wait_for_transfer_complete(void) {
|
|
||||||
while (tx_state != TX_DONE || rx_state != RX_DONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static inline void spi_wait_not_busy(void) {
|
|
||||||
// while ((SPI1->STATR & SPI_STATR_BSY) != 0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
void set_transfer_states(void) {
|
|
||||||
tx_state = TRANSMITTING;
|
|
||||||
rx_state = RECEIVING;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_transfer_states(void) {
|
|
||||||
tx_state = IDLE;
|
|
||||||
rx_state = IDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DMA1_HandleIrq(uint32_t channel_interrupt,
|
|
||||||
volatile transfer_state_t* state,
|
|
||||||
transfer_state_t active_state,
|
|
||||||
transfer_state_t done_state) {
|
|
||||||
if (DMA1->INTFR & channel_interrupt) { // check if DMA interrupt occurred
|
|
||||||
DMA1->INTFCR = channel_interrupt; // clear the interrupt flag
|
|
||||||
if (*state == active_state) {
|
|
||||||
*state = done_state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void DMA1_Channel3_IRQHandler(void) __attribute__((interrupt));
|
|
||||||
void DMA1_Channel2_IRQHandler(void) __attribute__((interrupt));
|
|
||||||
|
|
||||||
void DMA1_Channel3_IRQHandler(void) {
|
|
||||||
DMA1_HandleIrq(DMA1_IT_TC3, &tx_state, TRANSMITTING, TX_DONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DMA1_Channel2_IRQHandler(void) {
|
|
||||||
DMA1_HandleIrq(DMA1_IT_TC2, &rx_state, RECEIVING, RX_DONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void configure_dma(DMA_Channel_TypeDef* tx_channel, uint32_t tx_addr,
|
|
||||||
DMA_Channel_TypeDef* rx_channel, uint32_t rx_addr,
|
|
||||||
int rx_circular, uint16_t len) {
|
|
||||||
// disable DMA channels
|
|
||||||
tx_channel->CFGR &= ~DMA_CFGR1_EN;
|
|
||||||
rx_channel->CFGR &= ~DMA_CFGR1_EN;
|
|
||||||
|
|
||||||
// set memory addresses and transfer count
|
|
||||||
tx_channel->MADDR = tx_addr;
|
|
||||||
tx_channel->CNTR = len;
|
|
||||||
rx_channel->MADDR = rx_addr;
|
|
||||||
rx_channel->CNTR = len;
|
|
||||||
|
|
||||||
// set or clear the circular mode for RX
|
|
||||||
rx_channel->CFGR =
|
|
||||||
(rx_channel->CFGR & ~DMA_CFGR1_CIRC) | (rx_circular ? DMA_CFGR1_CIRC : 0);
|
|
||||||
|
|
||||||
// enable DMA channels
|
|
||||||
tx_channel->CFGR |= DMA_CFGR1_EN;
|
|
||||||
rx_channel->CFGR |= DMA_CFGR1_EN;
|
|
||||||
}
|
|
||||||
|
|
||||||
void spidma_read_buffer(uint8_t* buf, uint16_t len) {
|
|
||||||
set_transfer_states();
|
|
||||||
configure_dma(DMA1_Channel3, (uint32_t)&tx_dummy_byte, DMA1_Channel2,
|
|
||||||
(uint32_t)buf, 0, len);
|
|
||||||
|
|
||||||
wait_for_transfer_complete();
|
|
||||||
clear_transfer_states();
|
|
||||||
}
|
|
||||||
|
|
||||||
void spidma_write_buffer(uint8_t* buf, uint16_t len) {
|
|
||||||
set_transfer_states();
|
|
||||||
configure_dma(DMA1_Channel3, (uint32_t)buf, DMA1_Channel2, (uint32_t)rx_dummy,
|
|
||||||
1, len);
|
|
||||||
|
|
||||||
wait_for_transfer_complete();
|
|
||||||
clear_transfer_states();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t spi_transfer(uint8_t data) {
|
|
||||||
while (!(SPI1->STATR & SPI_STATR_TXE));
|
|
||||||
SPI1->DATAR = data;
|
|
||||||
|
|
||||||
while (!(SPI1->STATR & SPI_STATR_RXNE));
|
|
||||||
return SPI1->DATAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t spi_read_byte() { return spi_transfer(tx_dummy_byte); }
|
|
||||||
|
|
||||||
void spi_write_byte(uint8_t byte) { spi_transfer(byte); }
|
|
||||||
|
|
||||||
void spi_select(void) {
|
void spi_select(void) {
|
||||||
GPIOA->BCR = (1 << 4); // Set PA4 (CS) low
|
GPIOA->BCR = (1 << 4); // Set PA4 (CS) low
|
||||||
@@ -109,6 +17,68 @@ void spi_unselect(void) {
|
|||||||
GPIOA->BSHR = (1 << 4); // Set PA4 (CS) high
|
GPIOA->BSHR = (1 << 4); // Set PA4 (CS) high
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SPI DMA
|
||||||
|
void spidma_read_buffer(uint8_t* buf, uint16_t len) {
|
||||||
|
// tx
|
||||||
|
TX_Channel->MADDR = (uint32_t)&tx_dummy_byte;
|
||||||
|
TX_Channel->CNTR = len;
|
||||||
|
TX_Channel->CFGR &= ~DMA_MemoryInc_Enable;
|
||||||
|
// rx
|
||||||
|
RX_Channel->MADDR = (uint32_t)buf;
|
||||||
|
RX_Channel->CNTR = len;
|
||||||
|
RX_Channel->CFGR |= DMA_MemoryInc_Enable;
|
||||||
|
|
||||||
|
// enable
|
||||||
|
RX_Channel->CFGR |= DMA_CFGR1_EN;
|
||||||
|
TX_Channel->CFGR |= DMA_CFGR1_EN;
|
||||||
|
|
||||||
|
while (!(DMA1->INTFR & DMA1_FLAG_TC2) && !(DMA1->INTFR & DMA1_FLAG_TC3));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In transmission mode, when the DMA has written all the data to be
|
||||||
|
* transmitted (flag TCIF is set in the DMA_ISR register), the BSY flag can be
|
||||||
|
* monitored to ensure that the SPI communication is complete. This is
|
||||||
|
* required to avoid corrupting the last transmission before disabling the SPI
|
||||||
|
* or entering the Stop mode. The software must first wait until TXE=1 and
|
||||||
|
* then until BSY=0.
|
||||||
|
*/
|
||||||
|
while (!(SPI1->STATR & SPI_STATR_TXE));
|
||||||
|
while (SPI1->STATR & SPI_I2S_FLAG_BSY);
|
||||||
|
|
||||||
|
// clear intfr
|
||||||
|
DMA1->INTFCR |= DMA1_FLAG_TC2 | DMA1_FLAG_TC3;
|
||||||
|
|
||||||
|
RX_Channel->CFGR &= ~DMA_CFGR1_EN;
|
||||||
|
TX_Channel->CFGR &= ~DMA_CFGR1_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spidma_write_buffer(uint8_t* buf, uint16_t len) {
|
||||||
|
// tx
|
||||||
|
TX_Channel->MADDR = (uint32_t)buf;
|
||||||
|
TX_Channel->CNTR = len;
|
||||||
|
TX_Channel->CFGR |= DMA_MemoryInc_Enable;
|
||||||
|
// rx
|
||||||
|
RX_Channel->MADDR = (uint32_t)&rx_dummy;
|
||||||
|
RX_Channel->CNTR = len;
|
||||||
|
RX_Channel->CFGR &= ~DMA_MemoryInc_Enable;
|
||||||
|
|
||||||
|
// enable
|
||||||
|
TX_Channel->CFGR |= DMA_CFGR1_EN;
|
||||||
|
RX_Channel->CFGR |= DMA_CFGR1_EN;
|
||||||
|
|
||||||
|
while (!(DMA1->INTFR & DMA1_FLAG_TC2) && !(DMA1->INTFR & DMA1_FLAG_TC3));
|
||||||
|
|
||||||
|
// wait for SPI to complete: TXE = 1, then BSY = 0
|
||||||
|
while (!(SPI1->STATR & SPI_STATR_TXE));
|
||||||
|
while (SPI1->STATR & SPI_I2S_FLAG_BSY);
|
||||||
|
|
||||||
|
// clear intfr
|
||||||
|
DMA1->INTFCR |= DMA1_FLAG_TC2 | DMA1_FLAG_TC3;
|
||||||
|
|
||||||
|
RX_Channel->CFGR &= ~DMA_CFGR1_EN;
|
||||||
|
TX_Channel->CFGR &= ~DMA_CFGR1_EN;
|
||||||
|
}
|
||||||
|
|
||||||
void init_spidma(void) {
|
void init_spidma(void) {
|
||||||
// Enable clock for GPIOA and SPI1
|
// Enable clock for GPIOA and SPI1
|
||||||
RCC->APB2PCENR |= RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1;
|
RCC->APB2PCENR |= RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1;
|
||||||
@@ -116,16 +86,16 @@ void init_spidma(void) {
|
|||||||
RCC->AHBPCENR |= RCC_AHBPeriph_DMA1;
|
RCC->AHBPCENR |= RCC_AHBPeriph_DMA1;
|
||||||
|
|
||||||
// SPI1 Pin Configuration
|
// SPI1 Pin Configuration
|
||||||
// CS on PA4, 10MHz Output, open-drain
|
// CS on PA4, 10MHz Output, push-pull
|
||||||
GPIOA->CFGLR &= ~(0xf << (4 * 4));
|
GPIOA->CFGLR &= ~(0xf << (4 * 4));
|
||||||
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 4);
|
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 4);
|
||||||
// SCK on PA5, 10MHz Output, alt func, push-pull
|
// SCK on PA5, 10MHz Output, alt func, push-pull
|
||||||
GPIOA->CFGLR &= ~(0xf << (4 * 5));
|
GPIOA->CFGLR &= ~(0xf << (4 * 5));
|
||||||
GPIOA->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP_AF) << (4 * 5);
|
GPIOA->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP_AF) << (4 * 5);
|
||||||
// MOSI on PA7, 10MHz input, floating
|
// MISO on PA6, 10MHz input, floating
|
||||||
GPIOA->CFGLR &= ~(0xf << (4 * 6));
|
GPIOA->CFGLR &= ~(0xf << (4 * 6));
|
||||||
GPIOA->CFGLR |= (GPIO_CNF_IN_FLOATING) << (4 * 6);
|
GPIOA->CFGLR |= (GPIO_CNF_IN_FLOATING) << (4 * 6);
|
||||||
// MISO on PA6, 10MHz Output, alt func, push-pull
|
// MOSI on PA7, 10MHz Output, alt func, push-pull
|
||||||
GPIOA->CFGLR &= ~(0xf << (4 * 7));
|
GPIOA->CFGLR &= ~(0xf << (4 * 7));
|
||||||
GPIOA->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP_AF) << (4 * 7);
|
GPIOA->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP_AF) << (4 * 7);
|
||||||
|
|
||||||
@@ -135,8 +105,8 @@ void init_spidma(void) {
|
|||||||
SPI1->CTLR1 = SPI_Mode_Master | // Master mode
|
SPI1->CTLR1 = SPI_Mode_Master | // Master mode
|
||||||
SPI_Direction_2Lines_FullDuplex | // Full duplex
|
SPI_Direction_2Lines_FullDuplex | // Full duplex
|
||||||
SPI_DataSize_8b | // 8-bit data frame format
|
SPI_DataSize_8b | // 8-bit data frame format
|
||||||
SPI_CPOL_Low | // Clock polarity
|
SPI_CPHA_1Edge | // Clock polarity
|
||||||
SPI_CPHA_1Edge | // Clock phase
|
SPI_CPOL_Low | // Clock phase
|
||||||
SPI_BaudRatePrescaler_64 | // Baud rate prescaler
|
SPI_BaudRatePrescaler_64 | // Baud rate prescaler
|
||||||
SPI_NSS_Soft; // Software NSS management
|
SPI_NSS_Soft; // Software NSS management
|
||||||
|
|
||||||
@@ -147,22 +117,15 @@ void init_spidma(void) {
|
|||||||
SPI1->CTLR1 |= SPI_CTLR1_SPE; // Enable SPI
|
SPI1->CTLR1 |= SPI_CTLR1_SPE; // Enable SPI
|
||||||
|
|
||||||
// DMA setup
|
// DMA setup
|
||||||
DMA1_Channel3->PADDR = (uint32_t)&SPI1->DATAR; // TX Channel
|
TX_Channel->PADDR = (uint32_t)&SPI1->DATAR; // TX Channel
|
||||||
DMA1_Channel3->CFGR = DMA_M2M_Disable | DMA_Priority_VeryHigh |
|
TX_Channel->CFGR = DMA_M2M_Disable | DMA_Priority_VeryHigh |
|
||||||
DMA_MemoryDataSize_Byte | DMA_PeripheralDataSize_Byte |
|
DMA_MemoryDataSize_Byte | DMA_PeripheralDataSize_Byte |
|
||||||
DMA_MemoryInc_Enable | DMA_PeripheralInc_Disable |
|
DMA_MemoryInc_Enable | DMA_PeripheralInc_Disable |
|
||||||
DMA_Mode_Normal | DMA_DIR_PeripheralDST | DMA_IT_TC;
|
DMA_Mode_Normal | DMA_DIR_PeripheralDST;
|
||||||
|
|
||||||
DMA1_Channel2->PADDR = (uint32_t)&SPI1->DATAR; // RX Channel
|
RX_Channel->PADDR = (uint32_t)&SPI1->DATAR; // RX Channel
|
||||||
DMA1_Channel2->CFGR = DMA_M2M_Disable | DMA_Priority_VeryHigh |
|
RX_Channel->CFGR = DMA_M2M_Disable | DMA_Priority_VeryHigh |
|
||||||
DMA_MemoryDataSize_Byte | DMA_PeripheralDataSize_Byte |
|
DMA_MemoryDataSize_Byte | DMA_PeripheralDataSize_Byte |
|
||||||
DMA_MemoryInc_Enable | DMA_PeripheralInc_Disable |
|
DMA_MemoryInc_Enable | DMA_PeripheralInc_Disable |
|
||||||
DMA_Mode_Normal | DMA_DIR_PeripheralSRC | DMA_IT_TC;
|
DMA_Mode_Normal | DMA_DIR_PeripheralSRC;
|
||||||
|
|
||||||
// NVIC_SetPriority(DMA1_Channel2_IRQn, 0);
|
|
||||||
// NVIC_SetPriority(DMA1_Channel3_IRQn, 0);
|
|
||||||
NVIC_SetPriority(DMA1_Channel2_IRQn, 0x20);
|
|
||||||
NVIC_SetPriority(DMA1_Channel3_IRQn, 0x20);
|
|
||||||
NVIC_EnableIRQ(DMA1_Channel3_IRQn);
|
|
||||||
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
// ms counter
|
// ms counter
|
||||||
volatile uint32_t systick_millis = 0;
|
volatile uint32_t systick_millis = 0;
|
||||||
volatile int toggle_state = 0;
|
// volatile int toggle_state = 0;
|
||||||
|
|
||||||
void init_systick(void) {
|
void init_systick(void) {
|
||||||
SysTick->CTLR = 0;
|
SysTick->CTLR = 0;
|
||||||
@@ -27,12 +27,12 @@ void init_systick(void) {
|
|||||||
*/
|
*/
|
||||||
void SysTick_Handler(void) __attribute__((interrupt));
|
void SysTick_Handler(void) __attribute__((interrupt));
|
||||||
void SysTick_Handler(void) {
|
void SysTick_Handler(void) {
|
||||||
if (toggle_state) {
|
// if (toggle_state) {
|
||||||
GPIOB->BSHR = (1 << 9); // Set PB9 high
|
// GPIOB->BSHR = (1 << 9); // Set PB9 high
|
||||||
} else {
|
// } else {
|
||||||
GPIOB->BCR = (1 << 9); // Set PB9 low
|
// GPIOB->BCR = (1 << 9); // Set PB9 low
|
||||||
}
|
// }
|
||||||
toggle_state = !toggle_state;
|
// toggle_state = !toggle_state;
|
||||||
// Increment the Compare Register for the next trigger
|
// Increment the Compare Register for the next trigger
|
||||||
// If more than this number of ticks elapse before the trigger is reset,
|
// If more than this number of ticks elapse before the trigger is reset,
|
||||||
// you may miss your next interrupt trigger
|
// you may miss your next interrupt trigger
|
||||||
|
|||||||
10
src/w5500.c
10
src/w5500.c
@@ -58,7 +58,7 @@ void configure_network(void) {
|
|||||||
|
|
||||||
// Setup chip select and SPI callbacks
|
// Setup chip select and SPI callbacks
|
||||||
reg_wizchip_cs_cbfunc(spi_select, spi_unselect);
|
reg_wizchip_cs_cbfunc(spi_select, spi_unselect);
|
||||||
reg_wizchip_spi_cbfunc(spi_read_byte, spi_write_byte);
|
// reg_wizchip_spi_cbfunc(spi_read_byte, spi_write_byte);
|
||||||
reg_wizchip_spiburst_cbfunc(spidma_read_buffer, spidma_write_buffer);
|
reg_wizchip_spiburst_cbfunc(spidma_read_buffer, spidma_write_buffer);
|
||||||
|
|
||||||
uint8_t rx_tx_buff_sizes[] = {2, 2, 2, 2, 2, 2, 2, 2};
|
uint8_t rx_tx_buff_sizes[] = {2, 2, 2, 2, 2, 2, 2, 2};
|
||||||
@@ -76,10 +76,14 @@ void configure_dhcp(void) {
|
|||||||
callback_ip_conflict);
|
callback_ip_conflict);
|
||||||
|
|
||||||
// Attempt to acquire an IP address using DHCP
|
// Attempt to acquire an IP address using DHCP
|
||||||
while (!ip_assigned) {
|
// retry
|
||||||
|
uint8_t retries = 0;
|
||||||
|
|
||||||
|
while (!ip_assigned && retries < 30) {
|
||||||
DHCP_run();
|
DHCP_run();
|
||||||
Delay_Ms(100);
|
// Delay_Ms(100);
|
||||||
DEBUG_PRINT("DHCP_run()...\n");
|
DEBUG_PRINT("DHCP_run()...\n");
|
||||||
|
retries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ip_assigned) {
|
if (!ip_assigned) {
|
||||||
|
|||||||
Reference in New Issue
Block a user