first commit
This commit is contained in:
14
src/funconfig.h
Normal file
14
src/funconfig.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _FUNCONFIG_H
|
||||
#define _FUNCONFIG_H
|
||||
|
||||
// board definition file will already take care of this
|
||||
//#define CH32V003 1
|
||||
|
||||
#define FUNCONF_USE_HSI 0 // Use HSI Internal Oscillator
|
||||
#define FUNCONF_USE_HSE 1 // Use External Oscillator
|
||||
#define FUNCONF_SYSTEM_CORE_CLOCK 144000000 // System Core Clock in Hz
|
||||
#define FUNCONF_USE_DEBUGPRINTF 0
|
||||
#define FUNCONF_USE_UARTPRINTF 0
|
||||
#define FUNCONF_UART_PRINTF_BAUD 115200 // Only used if FUNCONF_USE_UARTPRINTF is set.
|
||||
|
||||
#endif
|
||||
166
src/main.c
Normal file
166
src/main.c
Normal file
@@ -0,0 +1,166 @@
|
||||
#include <DHCP/dhcp.h>
|
||||
#include <DNS/dns.h>
|
||||
#include <W5500/w5500.h>
|
||||
#include <socket.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ch32v003fun.h"
|
||||
#include "uart.h"
|
||||
#include "w5500.h"
|
||||
|
||||
#define DHCP_SOCKET 0
|
||||
#define DNS_SOCKET 1
|
||||
#define HTTP_SOCKET 2
|
||||
|
||||
volatile uint32_t count = 0;
|
||||
|
||||
void init_system(void) {
|
||||
SystemInit(); // from ch32v003fun.h
|
||||
|
||||
RCC->APB2PCENR |=
|
||||
RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB; // Enable GPIO clocks
|
||||
|
||||
setup_uart(UART_BRR_APB1); // 115200 baud
|
||||
}
|
||||
|
||||
void init_gpio(void) {
|
||||
// PA4 (CS)
|
||||
GPIOA->CFGLR &= ~(0xf << (4 * 4));
|
||||
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_OD) << (4 * 4);
|
||||
|
||||
// GPIO PB3 pp
|
||||
GPIOB->CFGLR &= ~(0xf << (4 * 3));
|
||||
GPIOB->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 3);
|
||||
|
||||
// GPIO PB4 pp
|
||||
GPIOB->CFGLR &= ~(0xf << (4 * 4));
|
||||
GPIOB->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 4);
|
||||
}
|
||||
|
||||
void init_spi(void) {
|
||||
// Enable SPI1
|
||||
RCC->APB2PCENR |= RCC_APB2Periph_SPI1;
|
||||
|
||||
// PA5 (SCK) alternate function, push-pull
|
||||
GPIOA->CFGLR &= ~(0xf << (4 * 5));
|
||||
GPIOA->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP_AF) << (4 * 5);
|
||||
// PA6 (MISO) input, floating
|
||||
GPIOA->CFGLR &= ~(0xf << (4 * 6));
|
||||
GPIOA->CFGLR |= (GPIO_CNF_IN_FLOATING) << (4 * 6);
|
||||
// PA7 (MOSI) alternate function, push-pull
|
||||
GPIOA->CFGLR &= ~(0xf << (4 * 7));
|
||||
GPIOA->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP_AF) << (4 * 7);
|
||||
|
||||
SPI1->CTLR1 = SPI_Direction_2Lines_FullDuplex | SPI_Mode_Master |
|
||||
SPI_DataSize_8b | SPI_CPOL_High | SPI_CPHA_2Edge | SPI_NSS_Soft |
|
||||
SPI_BaudRatePrescaler_4 | SPI_FirstBit_MSB;
|
||||
|
||||
SPI1->I2SCFGR &= SPI_Mode_Select; // Disable I2S mode
|
||||
// SPI1->CRCR = 7; // 8-bit CRC polynomial
|
||||
// SPI1->CTLR1 &= ~(SPI_CTLR1_DFF); // 8-bit data frame
|
||||
SPI1->CTLR1 |= CTLR1_SPE_Set;
|
||||
|
||||
// CS high initially
|
||||
GPIOA->BSHR = (1 << 4);
|
||||
}
|
||||
|
||||
volatile int ip_assigned = 0;
|
||||
|
||||
void Callback_IPAssigned(void) {
|
||||
printf("Callback: IP assigned! Leased time: %ld sec\r\n", getDHCPLeasetime());
|
||||
ip_assigned = 1;
|
||||
}
|
||||
|
||||
void Callback_IPConflict(void) { printf("Callback: IP conflict!\r\n"); }
|
||||
|
||||
// 1K should be enough, see https://forum.wiznet.io/t/topic/1612/2
|
||||
uint8_t dhcp_buffer[1024];
|
||||
// 1K seems to be enough for this buffer as well
|
||||
uint8_t dns_buffer[1024];
|
||||
|
||||
int main(void) {
|
||||
init_system();
|
||||
init_gpio();
|
||||
init_spi();
|
||||
|
||||
printf("SystemClk: %u\r\n", (unsigned)FUNCONF_SYSTEM_CORE_CLOCK);
|
||||
|
||||
printf("Registering W5500 callbacks...\r\n");
|
||||
reg_wizchip_cs_cbfunc(W5500_Select, W5500_Unselect);
|
||||
reg_wizchip_spi_cbfunc(W5500_ReadByte, W5500_WriteByte);
|
||||
// reg_wizchip_spiburst_cbfunc(W5500_ReadBuff, W5500_WriteBuff);
|
||||
|
||||
printf("Calling wizchip_init()...\r\n");
|
||||
uint8_t rx_tx_buff_sizes[] = {2, 2, 2, 2, 2, 2, 2, 2};
|
||||
wizchip_init(rx_tx_buff_sizes, rx_tx_buff_sizes);
|
||||
|
||||
printf("Calling DHCP_init()...\r\n");
|
||||
wiz_NetInfo net_info = {.mac = {0xEA, 0x11, 0x22, 0x33, 0x44, 0xEA},
|
||||
.dhcp = NETINFO_DHCP};
|
||||
// set MAC address before using DHCP
|
||||
setSHAR(net_info.mac);
|
||||
DHCP_init(DHCP_SOCKET, dhcp_buffer);
|
||||
|
||||
uint8_t version = getVERSIONR();
|
||||
|
||||
printf("W5500 VERSIONR: 0x%02X\n", version);
|
||||
|
||||
printf("Registering DHCP callbacks...\r\n");
|
||||
reg_dhcp_cbfunc(Callback_IPAssigned, Callback_IPAssigned,
|
||||
Callback_IPConflict);
|
||||
|
||||
printf("Calling DHCP_run()...\r\n");
|
||||
// actually should be called in a loop, e.g. by timer
|
||||
uint32_t ctr = 1e5;
|
||||
while ((!ip_assigned) && (ctr > 0)) {
|
||||
DHCP_run();
|
||||
ctr--;
|
||||
}
|
||||
if (!ip_assigned) {
|
||||
printf("\r\nIP was not assigned :(\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
getIPfromDHCP(net_info.ip);
|
||||
getGWfromDHCP(net_info.gw);
|
||||
getSNfromDHCP(net_info.sn);
|
||||
|
||||
uint8_t dns[4];
|
||||
getDNSfromDHCP(dns);
|
||||
|
||||
printf(
|
||||
"IP: %d.%d.%d.%d\r\nGW: %d.%d.%d.%d\r\nNet: %d.%d.%d.%d\r\nDNS: "
|
||||
"%d.%d.%d.%d\r\n",
|
||||
net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3],
|
||||
net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3],
|
||||
net_info.sn[0], net_info.sn[1], net_info.sn[2], net_info.sn[3], dns[0],
|
||||
dns[1], dns[2], dns[3]);
|
||||
|
||||
printf("Calling wizchip_setnetinfo()...\r\n");
|
||||
wizchip_setnetinfo(&net_info);
|
||||
|
||||
printf("Calling DNS_init()...\r\n");
|
||||
DNS_init(DNS_SOCKET, dns_buffer);
|
||||
|
||||
uint8_t addr[4];
|
||||
{
|
||||
char domain_name[] = "hye.su";
|
||||
printf("Resolving domain name \"%s\"...\r\n", domain_name);
|
||||
int8_t res = DNS_run(dns, (uint8_t*)&domain_name, addr);
|
||||
if (res != 1) {
|
||||
printf("DNS_run() failed, res = %d", res);
|
||||
return 1;
|
||||
}
|
||||
printf("Result: %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
GPIOB->BSHR = (1 << 3) | (1 << 4);
|
||||
printf("+%lu\n", count++);
|
||||
Delay_Ms(1000); // from ch32v003fun.h
|
||||
|
||||
GPIOB->BCR = (1 << 3) | (1 << 4);
|
||||
printf("-%lu\n", count++);
|
||||
Delay_Ms(1000);
|
||||
}
|
||||
}
|
||||
37
src/uart.c
Normal file
37
src/uart.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "uart.h"
|
||||
|
||||
#include "ch32v003fun.h"
|
||||
|
||||
// Write multiple chars to UART
|
||||
int _write(int fd, const char *buf, int size) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
while (!(USART2->STATR & USART_FLAG_TC)); // Wait for transmission complete
|
||||
USART2->DATAR = *buf++; // Send character
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
// Write a single char to UART
|
||||
int putchar(int c) {
|
||||
while (!(USART2->STATR & USART_FLAG_TC)); // Wait for transmission complete
|
||||
USART2->DATAR = (uint8_t)c; // Send character
|
||||
return 1;
|
||||
}
|
||||
|
||||
void setup_uart(int uart_brr) {
|
||||
// RCC->APB2PCENR |= RCC_APB2Periph_GPIOA; // Enable GPIOA on APB2
|
||||
RCC->APB1PCENR |= RCC_APB1Periph_USART2; // Enable USART2 on APB1
|
||||
|
||||
GPIOA->CFGLR &= ~(0xf << (4 * 2)); // Clear bits for PA2
|
||||
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)
|
||||
<< (4 * 2); // Set PA2 as AF
|
||||
|
||||
// USART configuration: 115200 baud rate, 8 data bits, no parity, 1 stop bit
|
||||
USART2->CTLR1 = USART_WordLength_8b | USART_Parity_No | USART_Mode_Tx;
|
||||
USART2->CTLR2 = USART_StopBits_1;
|
||||
USART2->CTLR3 = USART_HardwareFlowControl_None;
|
||||
|
||||
USART2->BRR = uart_brr;
|
||||
// Enable USART2
|
||||
USART2->CTLR1 |= CTLR1_UE_Set;
|
||||
}
|
||||
46
src/w5500.c
Normal file
46
src/w5500.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "w5500.h"
|
||||
|
||||
#include "ch32v003fun.h"
|
||||
|
||||
static inline uint8_t SPI_is_RX_empty() { return SPI1->STATR & SPI_STATR_RXNE; }
|
||||
|
||||
static inline void SPI_wait_not_busy() {
|
||||
while ((SPI1->STATR & SPI_STATR_BSY) != 0);
|
||||
}
|
||||
|
||||
static inline uint8_t SPI_transfer(uint8_t data) {
|
||||
while (!(SPI1->STATR & SPI_STATR_TXE));
|
||||
// SPI_wait_not_busy();
|
||||
SPI1->DATAR = data;
|
||||
|
||||
while (!(SPI1->STATR & SPI_STATR_RXNE));
|
||||
return SPI1->DATAR;
|
||||
}
|
||||
|
||||
void W5500_Select(void) {
|
||||
GPIOA->BCR = (1 << 4); // Set PA4 (CS) low
|
||||
// Delay_Ms(2);
|
||||
}
|
||||
|
||||
void W5500_Unselect(void) {
|
||||
GPIOA->BSHR = (1 << 4); // Set PA4 (CS) high
|
||||
// Delay_Ms(2);
|
||||
}
|
||||
|
||||
uint8_t W5500_ReadByte() {
|
||||
return SPI_transfer(0xFF); // dummy byte to init read
|
||||
}
|
||||
|
||||
void W5500_WriteByte(uint8_t byte) { SPI_transfer(byte); }
|
||||
|
||||
void W5500_ReadBuff(uint8_t* buffer, uint16_t len) {
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
buffer[i] = W5500_ReadByte();
|
||||
}
|
||||
}
|
||||
|
||||
void W5500_WriteBuff(uint8_t* buffer, uint16_t len) {
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
W5500_WriteByte(buffer[i]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user