diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2020-11-24 13:46:41 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2020-11-24 13:46:41 -0700 |
commit | 93b063fedfcf7409a67df035170ea5670cad22e1 (patch) | |
tree | a23321a7465d966b1ccf196ca00e65a70c9f9110 /02-usart/src | |
parent | b040195d31df6ad759f16ea3456471897f55daa1 (diff) | |
download | stm32l4-93b063fedfcf7409a67df035170ea5670cad22e1.tar.gz stm32l4-93b063fedfcf7409a67df035170ea5670cad22e1.tar.bz2 stm32l4-93b063fedfcf7409a67df035170ea5670cad22e1.zip |
Moved action to top level.
Removed old iterations of the project and moved the files from 02-usart
to the root directory since that's the sole place where the action is
and that subproject has outgrown its initial title.
Diffstat (limited to '02-usart/src')
-rw-r--r-- | 02-usart/src/arch/stm32l4xxx/peripherals/clock.c | 117 | ||||
-rw-r--r-- | 02-usart/src/arch/stm32l4xxx/peripherals/irq.c | 96 | ||||
-rw-r--r-- | 02-usart/src/arch/stm32l4xxx/peripherals/usart.c | 152 | ||||
-rw-r--r-- | 02-usart/src/kern/delay.c | 9 | ||||
-rw-r--r-- | 02-usart/src/kern/dma/dma_manager.c | 311 | ||||
-rw-r--r-- | 02-usart/src/kern/gpio/gpio_manager.c | 402 | ||||
-rw-r--r-- | 02-usart/src/kern/gpio/sysled.c | 14 | ||||
-rw-r--r-- | 02-usart/src/kern/init.c | 82 | ||||
-rw-r--r-- | 02-usart/src/kern/lib.c | 56 | ||||
-rw-r--r-- | 02-usart/src/kern/log.c | 55 | ||||
-rw-r--r-- | 02-usart/src/kern/main.c | 29 | ||||
-rw-r--r-- | 02-usart/src/kern/mem.c | 280 | ||||
-rw-r--r-- | 02-usart/src/kern/stdlibrepl.c | 13 | ||||
-rw-r--r-- | 02-usart/src/kern/string.c | 9 | ||||
-rw-r--r-- | 02-usart/src/kern/vector.c | 0 |
15 files changed, 0 insertions, 1625 deletions
diff --git a/02-usart/src/arch/stm32l4xxx/peripherals/clock.c b/02-usart/src/arch/stm32l4xxx/peripherals/clock.c deleted file mode 100644 index 9051572..0000000 --- a/02-usart/src/arch/stm32l4xxx/peripherals/clock.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file sets the system clock to its full glory of 80Mhz - */ - -#include "arch/stm32l4xxx/peripherals/clock.h" -#include "arch/stm32l4xxx/peripherals/flash.h" - -#include "kern/init.h" - -#include <stdint.h> - -#define TIMEOUT 10000 - - -int pll_off() -{ - uint32_t c; - - RCC.c_r &= ~BIT(24); /* Turn off pll. */ - for (c = 0; c < TIMEOUT && RCC.c_r & BIT(25); ++c) - ; /* Wait for OFF. */ - - if (c == TIMEOUT) { - return E_TIMEOUT; - } - - return 0; -} - -int pll_on() -{ - uint32_t c; - - RCC.c_r |= BIT(24); /* Turn on PLL. */ - for (c = 0; c < TIMEOUT && !(RCC.c_r & BIT(25)); ++c) - ; /* Wait for RDY. */ - - if (c == TIMEOUT) { - return E_TIMEOUT; - } - - return 0; -} - -int configure_pll( - uint8_t pllp_div_factor, pll_divisor_t pllr, /* System clock divisor. */ - pll_divisor_t pllq, /* Divison factor for PLL48M1CLK. */ - pllp_divisor_t pllp, /* Divison factor for PLLSAI2CLK. */ - uint8_t plln, /* PLL numerator. */ - pllm_divisor_t pllm, /* PLL denominator. */ - pll_src_t pllsrc /* PLL source */) -{ - if (RCC.c_r & BIT(25)) { - /* PLL must be off to configure it. */ - return E_NOT_OFF; - } - - /* Make sure inputs are valid. */ - if (pllp_div_factor == 1 || pllp_div_factor > 31) { - return E_BADPLLP_DIV; - } - if (plln < 8 || plln > 86) { - return E_BADPLLN; - } - - RCC.pllcfg_r = (pllp_div_factor << 27) | (pllr << 24) | (pllq << 20) | - (pllp << 16) | (plln << 8) | (pllm << 4) | (pllsrc << 0); - - return 0; -} - -static _no_init uint8_t clock_mHz; -uint8_t get_clock_mhz() -{ - return clock_mHz; -} - -int set_system_clock_MHz(uint8_t mhz) -{ - clock_mHz = mhz; - - /* Set the source of the system colck to MSI temporarily. */ - set_system_clock_src(SYSTEM_CLOCK_SRC_MSI); - - if (mhz <= 8 || mhz > 80) { - return E_BAD_ARG; - } - - pll_off(); - - configure_pll( - 0 /* pllp_div_factor */, PLL_DIVISOR_4 /* pllr: VCO / 4 = mhz MHz. */, - PLL_DIVISOR_4 /* pllq: VCO / 4 = mhz MHz */, PLLP_DIVISOR_7 /* pllp */, - - /* The following set the frequency of VCO to (mhz*4)MHz: mhz * 1 * 4MHz. - */ - mhz /* plln | mhz */, PLLM_DIVISOR_1 /* pllm | 01 */, - PLL_SRC_MSI /* pll src | 04 Mhz */); - - pll_on(); - - /* Configure the flash to have 4 wait states. This is required at - * 80 MHz. */ - FLASH.ac_r &= ~0x07; - FLASH.ac_r |= 0x04; - - /* Set the source of the system colck to PLL. */ - set_system_clock_src(SYSTEM_CLOCK_SRC_PLL); - return 0; -} - -int set_system_clock_src(system_clock_src_t src) -{ - uint8_t value = RCC.cfg_r & ~0x03; - RCC.cfg_r = value | src; - return 0; -} diff --git a/02-usart/src/arch/stm32l4xxx/peripherals/irq.c b/02-usart/src/arch/stm32l4xxx/peripherals/irq.c deleted file mode 100644 index 364b9a7..0000000 --- a/02-usart/src/arch/stm32l4xxx/peripherals/irq.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "arch/stm32l4xxx/peripherals/irq.h" -#include "arch/stm32l4xxx/peripherals/gpio.h" -#include "arch/stm32l4xxx/peripherals/nvic.h" - -#include "arch.h" -#include "kern/delay.h" -#include "kern/gpio/gpio_manager.h" - -#define IRQ_RESERVED(n) -#define IRQ(name, uname_, n) \ - void WEAK name () { \ - unhandled_isr(n); \ - } -#include "arch/stm32l4xxx/peripherals/isrs.inc" -#undef IRQ_RESERVED -#undef IRQ - -void isr_simple_pin_on() -{ - int ec; - gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; - gpio_reserved_pin_t pin3 = reserve_gpio_pin(GPIO_PIN_PB3, &opts, &ec); - - set_gpio_pin_high(pin3); -} - -#define IRQ_RESERVED(n) 0, -#define IRQ(name, uname_, n) name, -const void* vectors[] __attribute__((section(".vectors"))) = { - (void*)0x2000c000, /* Top of stack at top of sram1. 48k */ -#include "arch/stm32l4xxx/peripherals/isrs.inc" -}; -#undef IRQ_RESERVED -#undef IRQ - -/* Encodes the provided number as a series of flashes on the on-board - * LED. The flashes follow as such: - * - * Before the bits of the code are flashed, a rapid succession of 20 flashes - * followed by a pause will occur indicating that the next 8 flashes indicate - * the bits of the provided code. - * - * Eoch of the next eight flashes indicate either a 1 or 0 depending on the - * length of flash. The first flash is the least-significant bit, the next the - * second least, the third third least, etc. - * - * - A quick flash followed by a long pause indicates a 0 bit. - * - A "long" flash followed by a equally long pause indicates a 1 bit. - */ -void unhandled_isr(uint8_t number) -{ - int ec; - gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; - gpio_reserved_pin_t pin3 = reserve_gpio_pin(GPIO_PIN_PB3, &opts, &ec); - - for (;;) { - for (int i = 0; i < 20; ++ i) { - set_gpio_pin_high(pin3); - delay(1000000); - set_gpio_pin_low(pin3); - delay(1000000); - } - delay(50000000); - - int n = number; - for (int i = 0; i < 8; ++ i) { - if (n & 1) { - // LSB is a 1 - set_gpio_pin_high(pin3); - delay(15000000); - set_gpio_pin_low(pin3); - delay(15000000); - } else { - // LSB is a 0 - set_gpio_pin_high(pin3); - delay(1000000); - set_gpio_pin_low(pin3); - delay(29000000); - } - - n >>= 1; - } - } -} - -void enable_interrupts(interrupt_set_t* interrupts) -{ - for (int i = 0; i < sizeof(NVIC.ise_r) / sizeof(uint32_t); ++ i) - NVIC.ise_r[i] = interrupts->irqs[i]; -} - -void disable_interrupts(interrupt_set_t* interrupts) -{ - for (int i = 0; i < sizeof(NVIC.ise_r) / sizeof(uint32_t); ++ i) - NVIC.ice_r[i] = interrupts->irqs[i]; -} diff --git a/02-usart/src/arch/stm32l4xxx/peripherals/usart.c b/02-usart/src/arch/stm32l4xxx/peripherals/usart.c deleted file mode 100644 index 7309b48..0000000 --- a/02-usart/src/arch/stm32l4xxx/peripherals/usart.c +++ /dev/null @@ -1,152 +0,0 @@ -#include "arch/stm32l4xxx/peripherals/usart.h" -#include "kern/delay.h" -#include "kern/lib.h" -#include <stdarg.h> - -void set_usart1_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src) -{ - rcc->ccip_r = (rcc->ccip_r & (~0x03)) | usart_clk_src; -} - -void set_usart2_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src) -{ - rcc->ccip_r = (rcc->ccip_r & ~(0x03 << 2)) | (usart_clk_src << 2); -} - -void set_usart2_clock_enabled(__IO rcc_t* rcc, bool enable) -{ - if (enable) { - rcc->apb1en1_r |= BIT(17); - } else { - rcc->apb1en1_r &= ~BIT(17); - } -} - -void set_usart1_clock_enabled(__IO rcc_t* rcc, bool enable) -{ - if (enable) { - rcc->apb2en_r |= BIT(14); - } else { - rcc->apb2en_r &= ~BIT(14); - } -} - -void usart_set_parity(__IO usart_t* usart, usart_parity_t parity) -{ - uint32_t c_r1 = usart->c_r1; - c_r1 &= ~(0x3 << 9); - c_r1 |= parity; - usart->c_r1 = c_r1; -} - -void usart_set_enabled(__IO usart_t* usart, usart_enable_t enabled) -{ - if (!enabled) { - regset(usart->c_r1, usart_ue, 0); - } else { - /* Set the rx enabled. */ - regset(usart->c_r1, usart_re, !!(enabled & USART_ENABLE_RX)); - regset(usart->c_r1, usart_te, !!(enabled & USART_ENABLE_TX)); - regset(usart->c_r1, usart_ue, 1); - } -} - -void usart_transmit_byte_sync(__IO usart_t* usart, uint8_t byte) -{ - usart->td_r = byte; - /* Per the manual, when bit 7 of the IS register is set, then the usart - * data has been sent to the shift register. - * - * This bit is cleared by writing to the TD register. */ - while (!(usart->is_r & BIT(7))) - ; -} - -void usart_transmit_bytes_sync(__IO usart_t* usart, const uint8_t* bytes, uint32_t n) -{ - while (n --) { - usart_transmit_byte_sync(usart, *(bytes ++)); - } -} - -void usart_transmit_str_sync(__IO usart_t* usart, const char* str) -{ - while (*str) { - if (*str == '\n') { - usart_transmit_byte_sync(usart, '\r'); - } - usart_transmit_byte_sync(usart, *(str ++)); - } -} - -void usart_enable_dma(__IO usart_t* usart, usart_enable_t enabled) -{ - switch(enabled) { - case USART_ENABLE_DISABLED: - regset(usart->c_r3, usart_dmar, 0); - regset(usart->c_r3, usart_dmat, 0); - break; - - case USART_ENABLE_TX: - regset(usart->c_r3, usart_dmat, 1); - break; - - case USART_ENABLE_RX: - regset(usart->c_r3, usart_dmar, 1); - break; - }; -} - -void usart_vprintf(__IO usart_t* usart, const char* fmt, va_list l) -{ - union { - void* ptr; - char* str; - int i; - } b; - char buf[128]; - - while (*fmt != 0) { - if (*fmt == '%') { - switch (*(++fmt)) { - case 0: - goto end; - case '%': - usart_transmit_byte_sync(usart, '%'); - break; - case 'p': - b.ptr = va_arg(l, void*); - hexify(ptr2reg(b.ptr), buf); - usart_transmit_str_sync(usart, "0x"); - usart_transmit_str_sync(usart, buf); - break; - case 'd': - case 'i': - b.i = va_arg(l, int); - decimalify(b.i, buf); - usart_transmit_str_sync(usart, buf); - break; - case 's': - b.str = va_arg(l, char*); - usart_transmit_str_sync(usart, b.str); - } - ++ fmt; - } else { - if (*fmt == '\n') { - usart_transmit_byte_sync(usart, '\r'); - } - usart_transmit_byte_sync(usart, *(fmt ++)); - } - } - -end: - va_end(l); -} - -void usart_printf(__IO usart_t* usart, const char* fmt, ...) -{ - va_list l; - va_start(l, fmt); - - usart_vprintf(usart, fmt, l); -} diff --git a/02-usart/src/kern/delay.c b/02-usart/src/kern/delay.c deleted file mode 100644 index 28ef710..0000000 --- a/02-usart/src/kern/delay.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "kern/delay.h" - -void delay(uint32_t delay) -{ - while (delay--) { - /* needed to keep the compiler from optimizing away the loop. */ - asm volatile(""); - } -} diff --git a/02-usart/src/kern/dma/dma_manager.c b/02-usart/src/kern/dma/dma_manager.c deleted file mode 100644 index 00e9f3d..0000000 --- a/02-usart/src/kern/dma/dma_manager.c +++ /dev/null @@ -1,311 +0,0 @@ -#include "kern/dma/dma_manager.h" -#include "arch/stm32l4xxx/peripherals/dma.h" -#include "arch/stm32l4xxx/peripherals/usart.h" -#include "arch/stm32l4xxx/peripherals/rcc.h" - - -/* Bitmask of DMA2 channels in use. */ -static uint8_t dma_inuse[2]; - -static inline dma_t* get_dma(int dma) -{ - if (dma) { - return &DMA2; - } else { - return &DMA1; - } -} - -static dma_t* get_raw_dma(dma_channel_t chan) -{ - return get_dma(chan.dma); -} - -static dma_channel_config_t* get_raw_channel_config(dma_channel_t chan) -{ - dma_t* dma = get_raw_dma(chan); - return &dma->channel_config[chan.chan]; -} - -static uint32_t get_periph_location(dma_peripheral_t operipheral) -{ -#define CASE(p, n) case p: return ptr2reg(n); - switch (operipheral) { - CASE(DMA1_PERIPH_USART1_RX, &USART1.rd_r) - CASE(DMA1_PERIPH_USART1_TX, &USART1.td_r) - CASE(DMA1_PERIPH_USART2_RX, &USART2.rd_r) - CASE(DMA1_PERIPH_USART2_TX, &USART2.td_r) - - default: - return 0; - }; -#undef CASE -} - -static dma_channel_t allocate_dma_channel( - dma_peripheral_t operipheral, int* modesel) -{ - dma_peripheral_t peripheral = operipheral & 0xff; - int dmasel = peripheral >= DMA2_DMA1_SWITCH__; - if (dmasel) { - peripheral -= DMA2_DMA1_SWITCH__; - } - int chan = peripheral % DMA_N_CHANNELS; - - *modesel = peripheral / 7; - return (dma_channel_t) { - .dma = dmasel, - .chan = chan - }; -} - -/* - * Atomically reserves the DMA channel so other calls - * cannot erroneously reserve the same DMA channel. - * - * Returns 0 if this function was unable to reserve - * the channel. - */ -static int try_reserve_dma_channel( - dma_channel_t chan) -{ - int in_use = __sync_fetch_and_or( - &dma_inuse[chan.dma], 1 << chan.chan); - - return !(in_use & (1 << chan.chan)); -} - -void release_dma_channel(dma_channel_t chan) -{ - dma_channel_config_t* config = get_raw_channel_config(chan); - regset(config->cc_r, dma_cc_en, 0); /* Disable the register. */ - dma_inuse[chan.dma] &= ~(1 << chan.chan); /* Release the DMA. */ - - if (!dma_inuse[chan.dma]) { - /* Power-down the DMA if not in use. */ - if (chan.dma) { - regset(RCC.ahb1en_r, rcc_dma2en, 0); - } else { - regset(RCC.ahb1en_r, rcc_dma1en, 0); - } - } -} - -void configure_dma_channel( - dma_channel_t chan, - dma_peripheral_t operipheral, - dma_opts_t* opts, - dma_dir_t dir, - int selmode, - bool mem2mem, - int* error_out) -{ - if (chan.dma) { - regset(RCC.ahb1en_r, rcc_dma2en, 1); - } else { - regset(RCC.ahb1en_r, rcc_dma1en, 1); - } - - dma_t* dma = get_raw_dma(chan); - regset(dma->csel_r, 0xF << (4 * chan.chan), selmode); - dma_channel_config_t* config = - &dma->channel_config[chan.chan]; - - uint32_t reg = 0; - - regset(reg, dma_cc_dir, dir); - regset(reg, dma_cc_tcie, opts->transfer_complete_interrupt_enable); - regset(reg, dma_cc_htie, opts->half_transfer_interrupt_enable); - regset(reg, dma_cc_teie, opts->transfer_error_interrupt_enable); - regset(reg, dma_cc_circ, opts->circular_mode); - regset(reg, dma_cc_pinc, opts->peripheral_increment); - regset(reg, dma_cc_minc, opts->memory_increment); - regset(reg, dma_cc_psize, opts->peripheral_block_size); - regset(reg, dma_cc_msize, opts->memory_block_size); - regset(reg, dma_cc_pl, opts->priority); - regset(reg, dma_cc_mem2mem, mem2mem); - - config->cc_r = reg; - config->cpa_r = get_periph_location(operipheral); - - *error_out = 0; -} - -dma_mem2mem_channel_t select_dma_channel_mem2mem( - int channel, - dma_opts_t* opts, - int* error_out) -{ - -#define WRAP(c) ((dma_mem2mem_channel_t) { .c_ = c }) - // TODO this should probably be in a critical section. - dma_channel_t chan; - if (channel == -1) { - chan.dma = 1; - if ((dma_inuse[chan.dma] & 0x7F) == 0x7F) { - chan.dma = 0; - } - - if ((dma_inuse[chan.dma] & 0x7F) == 0x7F) { - *error_out = DMA_ERROR_CHANNEL_IN_USE; - return WRAP(DMA_CHAN_ERROR); - } - - uint8_t t = ~(dma_inuse[chan.dma] << 1); - chan.chan = 6 - (__builtin_clz(t) - 24); - } else { - if (channel < 7) { - chan.dma = 0; - chan.chan = channel; - } else { - chan.dma = 0; - chan.chan = channel - 7; - } - } - - if (!try_reserve_dma_channel(chan)) { - *error_out = DMA_ERROR_CHANNEL_IN_USE; - return WRAP(DMA_CHAN_ERROR); - } - - int ec = 0; - configure_dma_channel( - chan, - -1 /* No peripheral */, - opts, - READ_FROM_PERIPHERAL, - /* selmode = */ 0x8, - /* mem2mem = */ true, - &ec); - - if (ec) { - *error_out = ec; - return WRAP(DMA_CHAN_ERROR); - } - - *error_out = 0; - return WRAP(chan); -#undef WRAP -} - -dma_mem2p_channel_t select_dma_channel_mem2p( - dma_peripheral_t peripheral, - dma_opts_t* opts_in, - int* error_out) -{ -#define WRAP(c) ((dma_mem2p_channel_t) { .c_ = c }) - *error_out = 0; - - int modesel; - dma_channel_t ret = - allocate_dma_channel(peripheral, &modesel); - - if (!try_reserve_dma_channel(ret)) { - *error_out = DMA_ERROR_CHANNEL_IN_USE; - return WRAP(DMA_CHAN_ERROR); - } - - configure_dma_channel( - ret, - peripheral, - opts_in, - READ_FROM_MEMORY, - modesel, - /* mem2mem = */ false, - error_out); - - if (*error_out) { - return WRAP(DMA_CHAN_ERROR); - } - - *error_out = 0; - return WRAP(ret); -#undef WRAP -} - -dma_p2mem_channel_t select_dma_channel_p2mem( - dma_peripheral_t peripheral, - dma_opts_t* opts_in, - int* error_out) -{ -#define WRAP(c) ((dma_p2mem_channel_t) { .c_ = c }) - *error_out = 0; - - int modesel; - dma_channel_t ret = - allocate_dma_channel(peripheral, &modesel); - - if (!try_reserve_dma_channel(ret)) { - *error_out = DMA_ERROR_CHANNEL_IN_USE; - return WRAP(DMA_CHAN_ERROR); - } - - configure_dma_channel( - ret, - peripheral, - opts_in, - READ_FROM_PERIPHERAL, - modesel, - /* mem2mem = */ false, - error_out); - - if (*error_out) { - return WRAP(DMA_CHAN_ERROR); - } - - *error_out = 0; - return WRAP(ret); -#undef WRAP -} - - -void dma_mem2p_initiate_transfer( - dma_mem2p_channel_t chan, const void* from_loc, uint16_t nblocks) -{ - dma_channel_config_t* config = get_raw_channel_config(chan.c_); - config->cma_r = ptr2reg(from_loc); - config->cndt_r = nblocks; - - regset(config->cc_r, dma_cc_en, 1); -} - -void dma_mem2mem_initiate_transfer( - dma_mem2mem_channel_t chan, - void* to_loc, - const void* from_loc, - uint16_t nblocks) -{ - dma_channel_config_t* config = get_raw_channel_config(chan.c_); - config->cma_r = ptr2reg(to_loc); - config->cpa_r = ptr2reg(from_loc); - config->cndt_r = nblocks; - - regset(config->cc_r, dma_cc_en, 1); -} - -void dma_p2mem_initiate_transfer( - dma_p2mem_channel_t chan, void* to_loc, uint16_t nblocks) -{ - dma_channel_config_t* config = get_raw_channel_config(chan.c_); - - config->cma_r = ptr2reg(to_loc); - config->cndt_r = nblocks; - - regset(config->cc_r, dma_cc_en, 1); -} - -interrupt_t dma_channel_get_interrupt(dma_channel_t chan) -{ - if (chan.dma == 0) { - return IRQ_DMA1_CHANNEL1_IRQ + chan.chan; - } else { - switch (chan.chan) { - case 5: - return IRQ_DMA1_CHANNEL6_IRQ; - case 6: - return IRQ_DMA1_CHANNEL7_IRQ; - default: - return IRQ_DMA2_CHANNEL1_IRQ + chan.chan; - } - } -} diff --git a/02-usart/src/kern/gpio/gpio_manager.c b/02-usart/src/kern/gpio/gpio_manager.c deleted file mode 100644 index 82dd0ba..0000000 --- a/02-usart/src/kern/gpio/gpio_manager.c +++ /dev/null @@ -1,402 +0,0 @@ -#include "kern/gpio/gpio_manager.h" - -#include "arch/stm32l4xxx/peripherals/irq.h" -#include "arch/stm32l4xxx/peripherals/rcc.h" - -/* A list of whether the pins are in use or not as a bitmask. */ -uint32_t pins_inuse[N_GPIO_PINS / 32 + (N_GPIO_PINS % 32 != 0)]; - -struct gpio_afn_and_pin { - int8_t afn_number; - gpio_pin_t gpio_pin; -}; - -/* - * Returns which (pin, afn) pairs provide the given alternate function. - * The out array needs to have 5 positions. - * - * This function will use afn_number = -1 as the terminal. - * - * Note that EVENTOUT is a special case because all pins have an event out - * at afn=15 and should be assumed by other logic and thus is not handled - * by this function. - */ -static void get_ports_and_pins_for_alternate_function( - gpio_alternate_function_t afn, struct gpio_afn_and_pin* out) -{ - switch (afn) { -#define AFN1(fn, ...) \ - static_assert(false, "Unable to parse afn_table at " #fn); -#define AFN3(fn, ...) \ - static_assert(false, "Unable to parse afn_table at " #fn); -#define AFN5(fn, ...) \ - static_assert(false, "Unable to parse afn_table at " #fn); -#define AFN7(fn, ...) \ - static_assert(false, "Unable to parse afn_table at " #fn); - -#define AFN2(fn, afn, pin) \ - out[0].afn_number = afn; \ - out[0].gpio_pin = GPIO_PIN_ ## pin - -#define AFN4(fn, afn0, pin0, afn1, pin1) \ - AFN2(fn, afn0, pin0); \ - out[1].afn_number = afn1; \ - out[1].gpio_pin = GPIO_PIN_ ## pin1 - -#define AFN6(fn, afn0, pin0, afn1, pin1, afn2, pin2) \ - AFN4(fn, afn0, pin0, afn1, pin1); \ - out[2].afn_number = afn2; \ - out[2].gpio_pin = GPIO_PIN_ ## pin2 - -#define AFN8(fn, afn0, pin0, afn1, pin1, afn2, pin2, afn3, pin3) \ - AFN6(fn, afn0, pin0, afn1, pin1, afn2, pin2); \ - out[2].afn_number = afn3; \ - out[2].gpio_pin = GPIO_PIN_ ## pin3 - -#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME -#define GET_N(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME -#define AFN(fn, ...) \ - case GPIO_ALTERNATE_FUNCTION_ ## fn: \ - GET_MACRO(__VA_ARGS__, AFN8, AFN7, AFN6, AFN5, AFN4, AFN3, AFN2, AFN1)\ - (fn, __VA_ARGS__); \ - out[GET_N(__VA_ARGS__, 4, 4, 3, 3, 2, 2, 1, 1)] = \ - (struct gpio_afn_and_pin){-1, -1}; \ - break; - -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/afn_table.inc" - case GPIO_ALTERNATE_FUNCTION_EVENTOUT: - return; - } -} - -static inline int offset_for_gpio_pin(gpio_pin_t pin) -{ - switch (pin) { -#define PORT(p, pn) \ - case GPIO_PIN_P ## p ## pn: return pn; -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" -#undef PORT - case N_GPIO_PINS: return -1; - } - - /* Should be unreachable. */ - return -1; -} - -inline bool gpio_pin_in_use(gpio_pin_t pin) -{ - return !!(pins_inuse[pin / 32] & (1 << (pin % 32))); -} - -#define A(...) -#define B(...) -#define C(...) -#define D(...) -#define E(...) -#define F(...) -#define G(...) -#define H(...) -#define I(...) -#define SELECT_MACRO(PORT) PORT -#define PORT(port, pin) \ - SELECT_MACRO(port)(GPIO_PIN_P ## port ## pin, pin) -static int gc_port_a() -{ - return 0 -#undef A -#define A(abspin, relpin) \ - | (gpio_pin_in_use(abspin) << (relpin)) -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" - ; -#undef A -#define A(...) -} - -static int gc_port_b() -{ - return 0 -#undef B -#define B(abspin, relpin) \ - | (gpio_pin_in_use(abspin) << (relpin)) -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" - ; -#undef B -#define B(...) -} - -static int gc_port_c() -{ - return 0 -#undef C -#define C(abspin, relpin) \ - | (gpio_pin_in_use(abspin) << (relpin)) -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" - ; -#undef C -#define C(...) -} - -static int gc_port_d() -{ - return 0 -#undef D -#define D(abspin, relpin) \ - | (gpio_pin_in_use(abspin) << (relpin)) -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" - ; -#undef D -#define D(...) -} - -static int gc_port_e() -{ - return 0 -#undef E -#define E(abspin, relpin) \ - | (gpio_pin_in_use(abspin) << (relpin)) -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" - ; -#undef E -#define E(...) -} - -static int gc_port_f() -{ - return 0 -#undef F -#define F(abspin, relpin) \ - | (gpio_pin_in_use(abspin) << (relpin)) -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" - ; -#undef F -#define F(...) -} - -static int gc_port_g() -{ - return 0 -#undef G -#define G(abspin, relpin) \ - | (gpio_pin_in_use(abspin) << (relpin)) -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" - ; -#undef G -#define G(...) -} - -static int gc_port_h() -{ - return 0 -#undef H -#define H(abspin, relpin) \ - | (gpio_pin_in_use(abspin) << (relpin)) -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" - ; -#undef H -#define H(...) -} - -static int gc_port_i() -{ - return 0 -#undef I -#define I(abspin, relpin) \ - | (gpio_pin_in_use(abspin) << (relpin)) -#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/gpio/port_table.inc" - ; -#undef I -#define I(...) -} - - -static inline bool gpio_pin_try_reserve(gpio_pin_t pin) -{ - int in_use = __sync_fetch_and_or( - &pins_inuse[pin / 32], 1 << (pin % 32)); - return !(in_use & (1 << (pin % 32))); -} - -inline static gpio_port_config_t* get_gpio_port_config(gpio_port_t port) -{ - switch(port) { - case GPIO_PORT_A: return (gpio_port_config_t*) GPIOA_BASE; - case GPIO_PORT_B: return (gpio_port_config_t*) GPIOB_BASE; - case GPIO_PORT_C: return (gpio_port_config_t*) GPIOC_BASE; - case GPIO_PORT_H: return (gpio_port_config_t*) GPIOH_BASE; - default: return NULL; - } -} - -inline static gpio_port_config_t* get_gpio_port_config_for_pin(gpio_pin_t pin) -{ - gpio_port_t port = get_port_for_pin(pin); - return get_gpio_port_config(port); -} - -gpio_reserved_pin_t reserve_gpio_pin( - gpio_pin_t pin, gpio_pin_opts_t* opts, int* error_out) -{ - *error_out = 0; - if (!gpio_pin_try_reserve(pin)) { - *error_out = GPIO_ERROR_IN_USE; - return (gpio_reserved_pin_t) { .v_ = -1 }; - } - - gpio_port_t port = get_port_for_pin(pin); - regset(RCC.ahb2en_r, rcc_gpioen(port), 1); - - gpio_port_config_t* port_config = get_gpio_port_config(port); - - - int off = offset_for_gpio_pin(pin); - - regset(port_config->mode_r, gpio_mode_n(off), opts->mode); - regset(port_config->pupd_r, gpio_pupd_n(off), opts->pull_dir); - - switch(opts->mode) { - case GPIO_MODE_INPUT: - break; - - case GPIO_MODE_OUTPUT: - regset(port_config->ospeed_r, gpio_ospeed_n(off), opts->output_opts.speed); - regset(port_config->otype_r, gpio_otype_n(off), opts->output_opts.type); - break; - - case GPIO_MODE_ALTERNATE: - if (off < 8) { - regset( - port_config->af_rl, - gpio_afsel_n(off), - opts->alternate_opts.function); - } else { - regset( - port_config->af_rh, - gpio_afsel_n(off - 8), - opts->alternate_opts.function); - } - break; - - case GPIO_MODE_ANALOG: - regset(port_config->asc_r, gpio_asc_n(off), 1); - break; - } - - return (gpio_reserved_pin_t) { .v_ = pin }; -} - -gpio_reserved_pin_t gpio_enable_alternate_function( - gpio_alternate_function_t fn, - gpio_pin_t hint, - int* error_out) -{ - int i = 0; - gpio_pin_opts_t opts; - struct gpio_afn_and_pin afn_and_pin[5]; - - if (gpio_pin_out_of_range(hint) && hint != -1) { - *error_out = GPIO_ERROR_INVALID_PIN; - return (gpio_reserved_pin_t) { .v_ = -1 }; - } - - opts.mode = GPIO_MODE_ALTERNATE; - - if (fn == GPIO_ALTERNATE_FUNCTION_EVENTOUT) { - afn_and_pin[i].afn_number = GPIO_ALTERNATE_FUNCTION_EVENTOUT; - if (hint == -1) { - hint = GPIO_PIN_PA0; - } - afn_and_pin[i].gpio_pin = hint; - } else { - get_ports_and_pins_for_alternate_function(fn, afn_and_pin); - - if (hint == -1) { - hint = afn_and_pin[0].gpio_pin; - } - - for(i = 0; - i < 5 - && afn_and_pin[i].gpio_pin != hint - && afn_and_pin[i].gpio_pin != -1; - ++ i); - - if (afn_and_pin[i].gpio_pin == -1 || i == 5) { - *error_out = GPIO_ERROR_INVALID_PIN_FOR_ALTERNATE_FUNCTION; - return (gpio_reserved_pin_t) { .v_ = -1 }; - } - } - - opts.alternate_opts.function = afn_and_pin[i].afn_number; - return reserve_gpio_pin(afn_and_pin[i].gpio_pin, &opts, error_out); -} - -void release_gpio_pin(gpio_reserved_pin_t rpin) -{ - gpio_pin_t pin = rpin.v_; - // TODO this should be a critical section. - gpio_port_t port = get_port_for_pin(pin); - pins_inuse[pin / 32] &= ~(1 << (pin % 32)); - - int used; - switch(port) { - case GPIO_PORT_A: - used = gc_port_a(); - break; - case GPIO_PORT_B: - used = gc_port_b(); - break; - case GPIO_PORT_C: - used = gc_port_c(); - break; - case GPIO_PORT_D: - used = gc_port_d(); - break; - case GPIO_PORT_E: - used = gc_port_e(); - break; - case GPIO_PORT_F: - used = gc_port_f(); - break; - case GPIO_PORT_G: - used = gc_port_g(); - break; - case GPIO_PORT_H: - used = gc_port_h(); - break; - case GPIO_PORT_I: - used = gc_port_i(); - break; - - case N_GPIO_PORTS: - used = 1; - break; - } - - if (!used) { - regset(RCC.ahb2en_r, rcc_gpioen(port), 0); - } -} - -inline void get_gpio_pin_port_off( - gpio_pin_t pin, gpio_port_config_t** out_cfg, int* out_off) -{ - *out_cfg = get_gpio_port_config_for_pin(pin); - *out_off = offset_for_gpio_pin(pin); -} - -void set_gpio_pin_high(gpio_reserved_pin_t pin) -{ - int off; - gpio_port_config_t* portcfg; - get_gpio_pin_port_off(pin.v_, &portcfg, &off); - - regset(portcfg->od_r, (1 << off), 1); -} - -void set_gpio_pin_low(gpio_reserved_pin_t pin) -{ - int off; - gpio_port_config_t* portcfg; - get_gpio_pin_port_off(pin.v_, &portcfg, &off); - - regset(portcfg->od_r, (1 << off), 0); -} diff --git a/02-usart/src/kern/gpio/sysled.c b/02-usart/src/kern/gpio/sysled.c deleted file mode 100644 index a728da3..0000000 --- a/02-usart/src/kern/gpio/sysled.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "kern/gpio/sysled.h" - -#define SYSLED GPIO_PIN_PB3 - -gpio_reserved_pin_t get_sysled() -{ - if (gpio_pin_in_use(SYSLED)) { - return (gpio_reserved_pin_t) { .v_ = SYSLED }; - } - - int ec; - gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; - return reserve_gpio_pin(SYSLED, &opts, &ec); -} diff --git a/02-usart/src/kern/init.c b/02-usart/src/kern/init.c deleted file mode 100644 index 2531ca9..0000000 --- a/02-usart/src/kern/init.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "kern/init.h" - -#include "arch.h" -#include "arch/stm32l4xxx/peripherals/system.h" -#include "arch/stm32l4xxx/peripherals/clock.h" - -#include "kern/log.h" - -/* Forward-declare the main function. This is implemented in main.c. */ -int main(); - -/* These are defined in the linker script. */ - -#ifdef ARCH_STM32L4 -extern uint32_t INIT_DATA_VALUES; -extern uint32_t DATA_SEGMENT_START; -extern uint32_t DATA_SEGMENT_STOP; -extern uint32_t BSS_START; -extern uint32_t BSS_END; - -extern void(*INIT_ROUTINES_FLASH_START)(); -extern void(*INIT_ROUTINES_FLASH_STOP)(); - -init0() -{ - /* Enable a higher clock speed. This is the first thing we do - * beacuse it will boost the boot up time. */ - set_system_clock_MHz(80); -} - -init1() -{ - /* Next, we'll copy the data sections from flash to ram. */ - uint32_t* src; - uint32_t* dest; - - src = &INIT_DATA_VALUES; - dest = &DATA_SEGMENT_START; - - /* Copy the values from flash into the data segment. */ - while (dest != &DATA_SEGMENT_STOP) { - *(dest++) = *(src++); - } - - /* Everything in the BSS segment is set to zero. */ - dest = &BSS_START; - while (dest != &BSS_END) { - *(dest++) = 0; - } -} - -init3() -{ - klogf("--- System Restart ---\n"); - klogf("Setting the vector offset table to point to the start of flash.\n"); - - /* Set the vector offset table to be at the start - * of FLASH memory. */ - SCB.vto_r = 0x08000000; -} - -/* - * Runs before main. Initializes the data and bss segments by loading them - * into memory. - */ -_Noreturn void on_reset() -{ - void (**initfn)(); - for(initfn = &INIT_ROUTINES_FLASH_START; - initfn < &INIT_ROUTINES_FLASH_STOP; - ++ initfn) { - - (*initfn)(); - } - - /* Jump to main. */ - main(); - - for(;;); -} - -#endif /* ARCH_STM32L4 */ diff --git a/02-usart/src/kern/lib.c b/02-usart/src/kern/lib.c deleted file mode 100644 index 88188cc..0000000 --- a/02-usart/src/kern/lib.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "kern/lib.h" - -#define nybble_to_hex(n) \ - ((n) < 10 ? 0x30 + (n) : ('A' + ((n) - 10))) - -void hexify(uint32_t v, char* into) -{ - into += 8; - - *(into--) = 0; - - *(into--) = nybble_to_hex(v & 0x0F); - v >>= 4; - *(into--) = nybble_to_hex(v & 0x0F); - v >>= 4; - *(into--) = nybble_to_hex(v & 0x0F); - v >>= 4; - *(into--) = nybble_to_hex(v & 0x0F); - v >>= 4; - - *(into--) = nybble_to_hex(v & 0x0F); - v >>= 4; - *(into--) = nybble_to_hex(v & 0x0F); - v >>= 4; - *(into--) = nybble_to_hex(v & 0x0F); - v >>= 4; - *into = nybble_to_hex(v & 0x0F); - v >>= 4; -} - -void decimalify(int v, char* into) -{ - int c = 0; - int i; - - if (v == 0) { - *(into ++) = '0'; - *into = 0; - return; - } else { - while (v > 0) { - *(into ++) = 0x30 + (v % 10); - v /= 10; - ++ c; - } - } - *into = 0; - - into -= c; - for (i = 0; i < c / 2; ++ i) { - char tmp = into[i]; - into[i] = into[c - i - 1]; - into[c - i - 1] = tmp; - } - -} diff --git a/02-usart/src/kern/log.c b/02-usart/src/kern/log.c deleted file mode 100644 index a217183..0000000 --- a/02-usart/src/kern/log.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "arch/stm32l4xxx/peripherals/usart.h" -#include "arch/stm32l4xxx/peripherals/clock.h" - -#include "kern/log.h" -#include "kern/init.h" -#include "kern/gpio/gpio_manager.h" - -#include "kern/common.h" - -void setup_usart2(uint32_t baud_rate); - -/** This module requires an initialization routine. This is a level2 routine, - * so anything running at level3 or lower is guaranteed to have access - * to the klong. */ -init2() -{ - setup_usart2(115200); - regset(USART2.c_r1, usart_txeie, 1); - regset(USART2.c_r1, usart_rxneie, 1); - usart_set_enabled(&USART2, USART_ENABLE_TX | USART_ENABLE_RX); - - klogf("klog() enabled on USART2\n"); -} - -void klogf(const char* fmt, ...) -{ - va_list l; - va_start(l, fmt); - - usart_vprintf(&USART2, fmt, l); -} - -void setup_usart2(uint32_t baud_rate) -{ - enable_hsi(&RCC, true); - - int ec = 0; - gpio_enable_alternate_function( - GPIO_ALTERNATE_FUNCTION_USART2_TX, GPIO_PIN_PA2, &ec); - - gpio_enable_alternate_function( - GPIO_ALTERNATE_FUNCTION_USART2_RX, GPIO_PIN_PA15, &ec); - - set_usart2_clock_src(&RCC, USART_CLK_SRC_HSI16); - set_usart2_clock_enabled(&RCC, USART_CLK_SRC_HSI16); - - /* De-assert reset of USART2 */ - regset(RCC.apb1rst1_r, rcc_usart2rst, 0); - - USART2.c_r1 = 0; - USART2.c_r2 = 0; - USART2.c_r3 = 0; - - usart_set_divisor(&USART2, 16000000 / baud_rate); -} diff --git a/02-usart/src/kern/main.c b/02-usart/src/kern/main.c deleted file mode 100644 index ebb2164..0000000 --- a/02-usart/src/kern/main.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "arch.h" -#include "kern/log.h" - -#include "arch/stm32l4xxx/peripherals/system.h" -#include "arch/stm32l4xxx/peripherals/clock.h" - -void on_systick() /* Overrides weak-symbol on_systick. */ -{ - klogf("Systick\n"); -} - -#ifdef ARCH_STM32L4 - -/* Main function. This gets executed from the interrupt vector defined above. */ -int main() -{ - klogf("Hello, World! Clock Mhz: %d\n", (uint32_t) get_clock_mhz()); - - /* Set the countdown to start from 10,000,0000. */ - SCB.strv_r = 10000000; - - /* Enable interrupts. */ - regset(SCB.stcs_r, scb_tickint, 1); - - /* Start the systick. */ - regset(SCB.stcs_r, scb_enable, 1); -} - -#endif diff --git a/02-usart/src/kern/mem.c b/02-usart/src/kern/mem.c deleted file mode 100644 index 5234fff..0000000 --- a/02-usart/src/kern/mem.c +++ /dev/null @@ -1,280 +0,0 @@ -#include "arch.h" -#include "kern/mem.h" -#include "kern/common.h" - -#ifdef ARCH_STM32L4 -/* Provide a definition for memset() when not provided for the - * microcontroller. */ -void* memset(void* dest, int c, size_t n) -{ - uint8_t c8 = (uint8_t) c; - uint8_t* dest8 = (uint8_t*) dest; - uint8_t* to = dest8 + n; - - while(dest8 < to) { - *(dest8 ++) = c8; - } - - return dest; -} - -#else - -void* memset(void* dest, int c, size_t n); - -#endif - -typedef uint16_t halloc_off_t; - -#define CANARY 0x5a - -// The sizes will count the number of WORDS allocated. -// Since there's a max size of 16k, only 12 bits will be -// needed for this. -typedef struct HALLOC_NODE { - union { - uint32_t header; - struct { - /* Is this memory block currently in use (hasn't been hfree'd) */ - uint8_t used:1; - /* Number of words allocated. Does not include the header. */ - uint16_t size:12; - /* The location of the previous block (in WORDS from offest) */ - halloc_off_t prev:12; - uint8_t canary:7; - } PACKED; - }; - - uint8_t mem[]; /* The memory to use. */ -} halloc_node_t; - -static_assert(offsetof(halloc_node_t, mem) == 4, "Offset check failed."); - -halloc_node_t* halloc_start; - -#define halloc_node_out_of_range(node) \ - ((uint8_t*) (node) == ((uint8_t*)&DATA_SEGMENT_STOP) + MAX_HEAP_SIZE) - -#define halloc_node_next(cur) \ - ((halloc_node_t*)(((uint8_t*)(cur)) + (((cur)->size + 1) * 4))) - -#define halloc_node_prev(cur) halloc_node_at_off(cur->prev) - -#define halloc_node_at_off(offset) \ - ((halloc_node_t*)(((uint8_t*) halloc_start) + (offset) * 4)) - -#define halloc_node_get_off(node) \ - (((uint32_t)(((uint8_t*)(node)) - ((uint8_t*)(halloc_start)))) / 4) - -#define get_halloc_node(mem) \ - ((halloc_node_t*)(((uint8_t*)mem) - 4)) - -#define size_for(n) \ - (((n) / 4) + ((n) % 4 != 0)) - -void* halloc(size_t size) -{ - if (!halloc_start) { - halloc_start = (halloc_node_t*) DATA_SEGMENT_STOP_ADDR; - memset(halloc_start, 0, sizeof(halloc_node_t)); - halloc_start->size = (MAX_HEAP_SIZE / 4) - 1; - halloc_start->canary = CANARY; - } - - size_t realsz = size_for(size); /* Clip the size to the nearest word. */ - halloc_off_t offset = 0; - while (offset < (MAX_HEAP_SIZE / 4)) { - halloc_node_t* cur = halloc_node_at_off(offset); - - if (!cur->used && (cur->size >= realsz)) { - cur->used = true; - size_t orig_size = cur->size; - cur->size = realsz; - - if (orig_size > realsz) { - /* This halloc node needs to split into two blocks. */ - halloc_node_t* next = halloc_node_next(cur); - next->used = 0; - next->size = orig_size - realsz - sizeof(halloc_node_t) / 4; - next->prev = offset; - next->canary = CANARY; - - halloc_node_t* nextnext = halloc_node_next(next); - if (halloc_node_get_off(nextnext) < (MAX_HEAP_SIZE / 4)) { - nextnext->prev = halloc_node_get_off(next); - } - } - - return (void*) cur->mem; - } - - offset += (sizeof(halloc_node_t) / 4) + cur->size; - } - - return NULL; -} - - -/* Joins this node with the previous and next nodes if they're free. */ -static void coalesce(halloc_node_t* cur) -{ - halloc_node_t* orig = cur; - halloc_node_t* last_freed; - halloc_node_t* next_used; - - /* Find the earliest contiguous free'd block. */ - while (!cur->used && cur != halloc_start) { - cur = halloc_node_prev(cur); - } - - if (cur == halloc_start && !cur->used) { - last_freed = cur; - } else { - last_freed = halloc_node_next(cur); - } - - /* Find the next used block. */ - cur = orig; - while (!cur->used && !halloc_node_out_of_range(cur)) { - cur = halloc_node_next(cur); - } - - next_used = cur; - - if (!halloc_node_out_of_range(next_used)) { - next_used->prev = halloc_node_get_off(last_freed); - } - - last_freed->size = ((uint8_t*) next_used - (last_freed->mem)) / 4; -} - -#ifdef FOR_TESTING -#include <assert.h> -#include <stdio.h> -void panic(const char* x) -{ - fprintf(stderr, "%s\n", x); - assert(0); -} -#else -void panic(const char* x) -{ - for(;;); -} -#endif - -void hfree(void* mem) -{ - /* Like normal free(), do nothing on free'ing NULL */ - if (!mem) return; - - halloc_node_t* header = get_halloc_node(mem); - if (!header->used) { - panic("Heap double free or corruption!\n"); - return; - } - - header->used = 0; - coalesce(header); -} - -#ifdef FOR_TESTING - -#include <stdio.h> - -void* debug_halloc_get_next_ptr(void* ptr) -{ - halloc_node_t* node = ptr - sizeof(halloc_node_t); - halloc_node_t* next = halloc_node_next(node); - - return next->mem; -} - -void* debug_halloc_get_prev_ptr(void* ptr) -{ - halloc_node_t* node = ptr - sizeof(halloc_node_t); - halloc_node_t* prev = halloc_node_prev(node); - - return prev->mem; -} - -void debug_print_blocks() -{ - printf("------ Print Blocks -------\n"); - halloc_node_t* cur = halloc_node_at_off(0); - - while (!halloc_node_out_of_range(cur)) { - printf("header (%04x) {used=%d, size=%5d, prev=%04x, canary=%02x}\n", - halloc_node_get_off(cur), cur->used, cur->size, cur->prev, cur->canary); - cur = halloc_node_next(cur); - } -} - -/* Tests that we can walk up and down the allocated blocks and that they - * are properly aligned. */ -int debug_halloc_assert_consistency(char* error, size_t len) -{ - halloc_node_t* cur = halloc_node_at_off(0); - size_t total_size = 0; - size_t loop_check = 0; - size_t n_blocks = 1; - size_t n_blocks_back = 1; - - while(1) { - if (cur->canary != CANARY) { - snprintf(error, len, "Node has corrupted canary. %02x vs expected %02x\n", - cur->canary, CANARY); - return 1; - } - - total_size += cur->size + 1; - - halloc_node_t* next = halloc_node_next(cur); - if ((uint8_t*) next == ((uint8_t*)&DATA_SEGMENT_STOP) + MAX_HEAP_SIZE) { - break; - } else if ((uint8_t*) next > (uint8_t*)DATA_SEGMENT_STOP_ADDR + MAX_HEAP_SIZE){ - snprintf( - error, len, "Next node points is out of bounds. %p vs max of %p\n", - next, - (void*)(DATA_SEGMENT_STOP_ADDR + MAX_HEAP_SIZE)); - return 1; - } - - cur = next; - ++ n_blocks; - } - - if (total_size * 4 != MAX_HEAP_SIZE) { - snprintf( - error, len, "Total recorded size is inconsistent. %lu vs %lu\n", - total_size * 4, MAX_HEAP_SIZE); - return 1; - } - - if (cur == halloc_start) { - return 0; - } - - while (loop_check < 10000) { - halloc_node_t* prev = halloc_node_prev(cur); - ++ n_blocks_back; - - if (prev == halloc_start) { - if (n_blocks != n_blocks_back) { - snprintf( - error, len, "Different number of blocks found on the way back. Found %lu on the way back vs %lu up.\n", - n_blocks_back, n_blocks); - return 1; - } - return 0; - } - - cur = prev; - ++ loop_check; - } - - snprintf(error, len, "Loop check failed.\n"); - return 1; -} - -#endif diff --git a/02-usart/src/kern/stdlibrepl.c b/02-usart/src/kern/stdlibrepl.c deleted file mode 100644 index 2d9d839..0000000 --- a/02-usart/src/kern/stdlibrepl.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Replacement for common stdlib functions that don't exist - * on the ARM bare-metal compilation environment. - */ - -#include <stddef.h> - -size_t strlen(char* ch) -{ - size_t ret = 0; - while(*(ch ++) != 0) ++ ret; - return ret; -} diff --git a/02-usart/src/kern/string.c b/02-usart/src/kern/string.c deleted file mode 100644 index 4afa228..0000000 --- a/02-usart/src/kern/string.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "kern/string.h" - -void kstrcpy(char* into, const char* from) -{ - while(*from) { - *(into ++) = *(from ++); - } - *into = 0; -} diff --git a/02-usart/src/kern/vector.c b/02-usart/src/kern/vector.c deleted file mode 100644 index e69de29..0000000 --- a/02-usart/src/kern/vector.c +++ /dev/null |