first commit

This commit is contained in:
2024-10-10 00:45:09 +06:00
commit e56944bbcd
89 changed files with 31498 additions and 0 deletions

14
src/funconfig.h Normal file
View 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
View 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
View 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
View 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]);
}
}