Skip to content
Snippets Groups Projects
Commit 47e2dd08 authored by Jakob's avatar Jakob
Browse files

copied and adapted example from mdk, added init and config uart

parent 6d7ead53
No related branches found
No related tags found
1 merge request!1copied and adapted example from mdk, added init and config uart
SOURCES = main.c
include $(MDK)/$(ARCH)/build.mk
// Copyright (c) Charles Lohr
// All rights reserved
#include <mdk.h>
#define C3_SYSTEM_PERIP_CLK_EN0_REG ((volatile uint32_t *)0x0010)
// SYSTEM_UART_MEM_CLK_EN is on 24
// SYSTEM_UARTn_CLK_EN n=0 is on 2, n=1 is on 5
#define C3_UART_CLKDIV_REG ((volatile uint32_t *)0x0014)
// UART_CLKDIV - integer part of baud rate calculator devisor - 0 to 11
// UART_CLKDIV_FRAG - numerator of devisor in baud rate calculator devisor
#define C3_UART_RX_FILT_REG ((volatile uint32_t *)0x0018)
// SYSTEM_UARTn_RST n=0 is on 2, n=1 is on 5
#define C3_UART_CONF0_REG ((volatile uint32_t *)0x0020)
// UART_PARITY is on 0
// UART_PARITY_EN is on 1
// UART_BIT_NUM is on 2 and 3
#define C3_UART_CLK_CONF_REG ((volatile uint32_t *)0x0078)
// UART_RST_CORE is on 23
// UART_SCLK_SEL is on 20 and 21 (2 bits), selcetion is between 1 and 3
// UART_SCLK_DIV_NUM - The integral part of the frequency divisor - 12 to 19
// UART_SCLK_DIV_A - The numerator of the frequency divisor - 6 to 11
// UART_SCLK_DIV_B - The denominator of the frequency divisor - 0 to 5
#define C3_UART_ID_REG ((volatile uint32_t *)0x0080)
// UART_UPDATE_CTRL is on 30
// UART_REG_UPDATE is on 31
// On the ESP32C3 dev boards, the WS2812 LED is connected to GPIO 8
static int ws_2812_pin = 8;
static void init_uart_enable_clk(){
// enable the clock for UART RAM by setting SYSTEM_UART_MEM_CLK_EN to 1;
// enable APB_CLK for UARTn by setting SYSTEM_UARTn_CLK_EN to 1;
uint32_t perip_clk_en0_reg = *C3_SYSTEM_PERIP_CLK_EN0_REG;
perip_clk_en0_reg |= 1<<24;
perip_clk_en0_reg |= 1<<5;
perip_clk_en0_reg |= 1<<2;
*C3_SYSTEM_PERIP_CLK_EN0_REG = perip_clk_en0_reg;
}
static void init_uart_toggle_rst(){
// Detailed steps explained in 26.5.2.1
// for resetting and initilizing of uart
// get current regestry values
uint32_t rx_filt_reg = *C3_UART_RX_FILT_REG;
uint32_t core_value = *C3_UART_CLK_CONF_REG;
// clear UARTn_RST
rx_filt_reg &= (uint32_t)~(1<<5);
rx_filt_reg &= (uint32_t)~(1<<2);
*C3_UART_RX_FILT_REG = rx_filt_reg;
// set UART_RST_CORE
core_value |= 1<<23;
*C3_UART_CLK_CONF_REG = core_value;
// set UARTn_RST
rx_filt_reg |= 1<<5;
rx_filt_reg |= 1<<2;
*C3_UART_RX_FILT_REG = rx_filt_reg;
// clear UARTn_RST
rx_filt_reg &= (uint32_t)~(1<<5);
rx_filt_reg &= (uint32_t)~(1<<2);
*C3_UART_RX_FILT_REG = rx_filt_reg;
// clear UART_RST_CORE
core_value &= (uint32_t)~(1<<23);
*C3_UART_CLK_CONF_REG = core_value;
}
static void init_uart_clear_update(){
// enable register synchronization by clearing UART_UPDATE_CTRL.
uint32_t id_value = *C3_UART_ID_REG;
id_value &= (uint32_t)~(1<<30);
*C3_UART_ID_REG = id_value;
}
static void config_clock_freq(){
//freq = clock source rate / (UART_SCLK_DIV_NUM+UART_SCLK_DIV_A/UART_SCLK_DIV_B)
// baud rate = freq / (UART_CLKDIV + UART_CLKDIV_FRAG / 16)
// select the clock source via UART_SCLK_SEL;
uint32_t clockSelect = *C3_UART_CLK_CONF_REG;
// making sure we start with 0
clockSelect &= (uint32_t)~(1<<20);
clockSelect &= (uint32_t)~(1<<21);
// 01 is ABP_CLK with 80 MHz
// 10 is RC_FAST_CLK with default of 17.5 MHz
// 11 is XTAL_CLK with 40 MHz
clockSelect |= 1<<20;
*C3_UART_CLK_CONF_REG = clockSelect;
// selected ABP_CLK with 80 MHz
// dividing clock to 6 Mhz (divisor should be 13+1/3)
// UART_SCLK_DIV_NUM
clockSelect |= 1<<12;
clockSelect |= 1<<14;
clockSelect |= 1<<15;
// UART_SCLK_DIV_A
clockSelect |= 1<<6;
// UART_SCLK_DIV_B
clockSelect |= 1<<1;
clockSelect |= 1<<0;
*C3_UART_CLK_CONF_REG = clockSelect;
// calculate Baud rate to be 9600 (6Mhz/625)
uint32_t baudRateDivs = *C3_UART_CLKDIV_REG;
baudRateDivs |= 1<<0;
baudRateDivs |= 1<<4;
baudRateDivs |= 1<<5;
baudRateDivs |= 1<<6;
baudRateDivs |= 1<<9;
*C3_UART_CLKDIV_REG = baudRateDivs;
}
static void disable_parity(){
uint32_t uart_conf_reg = *C3_UART_CONF0_REG;
uart_conf_reg &= (uint32_t)~(1<<0);
uart_conf_reg &= (uint32_t)~(1<<1);
*C3_UART_CONF0_REG = uart_conf_reg;
}
static void set_max_data_lenght(){
uint32_t uart_conf_reg = *C3_UART_CONF0_REG;
uart_conf_reg |= (1<<2);
uart_conf_reg |= (1<<3);
*C3_UART_CONF0_REG = uart_conf_reg;
}
static void config_uart(){
printf("Try to config %d\n", 1);
// wait for UART_REG_UPDATE to become 0, which indicates the completion of the last synchronization;
uint32_t reg_update = *C3_UART_ID_REG;
if ((bool)(reg_update & (uint32_t)(1<<31))){
return;
}
printf("Ready to config %d\n", 1);
// configure static registers (if any) following Section 26.5.1.2;
// set clock freq to 6MHz
// baud rate to 9600
config_clock_freq();
// configure data length via UART_BIT_NUM;
set_max_data_lenght();
// configure odd or even parity check via UART_PARITY_EN and UART_PARITY;
disable_parity();
// synchronize the configured values to the Core Clock domain by writing 1 to UART_REG_UPDATE.
reg_update |= (uint32_t)(1<<31);
*C3_UART_ID_REG = reg_update;
}
static void enable_uart_transmitter(){
// configure TX FIFO’s empty threshold via UART_TXFIFO_EMPTY_THRHD;
// disable UART_TXFIFO_EMPTY_INT interrupt by clearing UART_TXFIFO_EMPTY_INT_ENA;
// write data to be sent to UART_RXFIFO_RD_BYTE;
// clear UART_TXFIFO_EMPTY_INT interrupt by setting UART_TXFIFO_EMPTY_INT_CLR;
// enable UART_TXFIFO_EMPTY_INT interrupt by setting UART_TXFIFO_EMPTY_INT_ENA;
// detect UART_TXFIFO_EMPTY_INT and wait for the completion of data transmission.
}
//static void reset_uart(){
// 26.4.1 Clock and Reset
// init_uart_enable_clk();
// init_uart_toggle_rst();
//}
static void init_uart(){
// from technical reference manual 543 f
init_uart_enable_clk();
init_uart_toggle_rst();
init_uart_clear_update();
}
// Simple hue function for generation of smooth rainbow.
static uint8_t hueval(int value) {
value = value % 1536;
if (value < 256) {
return (uint8_t) value;
} else if (value < 768) {
return 255;
} else if (value < 1024) {
return (uint8_t) (1023 - value);
} else {
return 0;
}
}
static void blink(int count, unsigned long delay_millis) {
uint8_t green[3] = {1, 0, 0}, black[3] = {0, 0, 0};
for (int i = 0; i < count; i++) {
ws2812_show(ws_2812_pin, green, sizeof(green));
delay_ms(delay_millis);
ws2812_show(ws_2812_pin, black, sizeof(black));
delay_ms(delay_millis);
}
}
static void rainbow(int count) {
for (int i = 0; i < count; i++) {
uint8_t val = hueval(i);
val = (uint8_t) (val/100);
uint8_t rgb[3] = {0, val, val};
ws2812_show(ws_2812_pin, rgb, sizeof(rgb));
delay_ms(1);
}
}
int main(void) {
wdt_disable();
gpio_output(ws_2812_pin);
init_uart();
config_uart();
enable_uart_transmitter();
uint8_t cycle = 0;
for (;;) {
printf("Cycle %d\n", cycle++);
blink(2, 200);
rainbow(2500);
}
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment