aboutsummaryrefslogtreecommitdiff
path: root/02-usart/src/core/usart.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2020-11-18 21:11:01 -0700
committerJosh Rahm <joshuarahm@gmail.com>2020-11-18 21:16:12 -0700
commitc1405b06d98b9b227fa7ff53c158f31d745eb505 (patch)
tree77397453c2b0e20bbb4136aa52836fe3eb0e41e6 /02-usart/src/core/usart.c
parent44c2d2d5e5ce43563a4912b2967cdb6b2039b6dd (diff)
downloadstm32l4-c1405b06d98b9b227fa7ff53c158f31d745eb505.tar.gz
stm32l4-c1405b06d98b9b227fa7ff53c158f31d745eb505.tar.bz2
stm32l4-c1405b06d98b9b227fa7ff53c158f31d745eb505.zip
Reorganize some file. Put thte core register libraries in a core/
subdirectory.
Diffstat (limited to '02-usart/src/core/usart.c')
-rw-r--r--02-usart/src/core/usart.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/02-usart/src/core/usart.c b/02-usart/src/core/usart.c
new file mode 100644
index 0000000..8f58d8b
--- /dev/null
+++ b/02-usart/src/core/usart.c
@@ -0,0 +1,145 @@
+#include "core/usart.h"
+#include "delay.h"
+#include "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)
+{
+ uint32_t c_r1 = usart->c_r1;
+
+ if (!enabled) {
+ usart->c1_bf.ue = 0;
+ } else {
+ /* Set the rx enabled. */
+ usart->c1_bf.re = !!(enabled & USART_ENABLE_RX);
+ usart->c1_bf.te = !!(enabled & USART_ENABLE_TX);
+ usart->c1_bf.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:
+ usart->c3_bf.dmar = 0;
+ usart->c3_bf.dmat = 0;
+ break;
+
+ case USART_ENABLE_TX:
+ usart->c3_bf.dmat = 1;
+ break;
+
+ case USART_ENABLE_RX:
+ usart->c3_bf.dmar = 1;
+ break;
+ };
+}
+
+void usart_printf(__IO usart_t* usart, const char* fmt, ...)
+{
+ va_list l;
+ union {
+ void* ptr;
+ int i;
+ } b;
+ char buf[128];
+
+ va_start(l, fmt);
+
+ 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;
+ }
+ ++ fmt;
+ } else {
+ if (*fmt == '\n') {
+ usart_transmit_byte_sync(usart, '\r');
+ }
+ usart_transmit_byte_sync(usart, *(fmt ++));
+ }
+ }
+
+end:
+ va_end(l);
+}