From 17f768a478094929d5f14e434ed5b5bb542814e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Mon, 28 Dec 2015 22:37:24 +0100 Subject: [PATCH] workign usart --- Makefile | 1 + lib/common.h | 16 +++-- lib/defs_base.h | 142 +++++++++++++++++++++++++++++---------------- lib/defs_flash.h | 38 ++++++------ lib/defs_gpio.h | 61 ++++++++++--------- lib/defs_rcc.h | 28 ++++----- lib/defs_systick.h | 8 +-- lib/defs_usart.h | 80 ++++++++++++++----------- lib/gpio.c | 46 ++++++++++----- lib/usart.c | 84 +++++++++++++++++++++++++++ lib/usart.h | 31 ++++++++++ main.c | 13 +++-- proj.pro | 6 +- 13 files changed, 381 insertions(+), 173 deletions(-) create mode 100644 lib/usart.c create mode 100644 lib/usart.h diff --git a/Makefile b/Makefile index d5c824e..34050da 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ STARTUP_SCRIPT = startup_stm32l100xc.s OBJS += $(BINARY).o $(STARTUP_SCRIPT:.s=.o) OBJS += lib/gpio.o OBJS += lib/systick.o +OBJS += lib/usart.o ################################################################ diff --git a/lib/common.h b/lib/common.h index ee35f7d..97c2c88 100644 --- a/lib/common.h +++ b/lib/common.h @@ -6,11 +6,16 @@ #include +typedef volatile uint8_t* io8_t; +typedef volatile uint16_t* io16_t; +typedef volatile uint32_t* io32_t ; +typedef volatile uint64_t* io64_t; + /* Generic memory-mapped I/O accessor functions */ -#define MMIO8(addr) (*(volatile uint8_t *)(addr)) -#define MMIO16(addr) (*(volatile uint16_t *)(addr)) -#define MMIO32(addr) (*(volatile uint32_t *)(addr)) -#define MMIO64(addr) (*(volatile uint64_t *)(addr)) +#define MMIO8(addr) (*(io8_t)(addr)) +#define MMIO16(addr) (*(io16_t)(addr)) +#define MMIO32(addr) (*(io32_t)(addr)) +#define MMIO64(addr) (*(io64_t)(addr)) /* Generic bit-band I/O accessor functions */ #define BBIO_SRAM(addr, bit) \ @@ -22,6 +27,9 @@ // i...iterator, m...mask, count...nr of bits #define BitFieldLoop(i, m, count) for (uint32_t i = 0, m = 1; i < count; m <<= 1, i++) +#define P_REG(periph_base, reg_offs) ((io32_t) ((periph_base) + (reg_offs))) + +#define BIT(x) (1 << (x)) #define BIT0 (1<<0) #define BIT1 (1<<1) diff --git a/lib/defs_base.h b/lib/defs_base.h index 5fd04d8..3fc6ba1 100644 --- a/lib/defs_base.h +++ b/lib/defs_base.h @@ -18,83 +18,125 @@ // ------------------------- System Config Blocks ----------------------------- -#define _SCS_BASE 0xE000E000 // System Control Space base -#define _SCB (_SCS_BASE + 0x0D00) // System Control Block base -#define _NVIC (_SCS_BASE + 0x0100) // Nested Interrupt Vector Controller base -#define _OB 0x1FF80000 // FLASH Option Bytes base address -#define _AES 0x50060000 // Encryption module -#define _FSMC 0xA0000000 // External Memory Control base -#define _DBGMCU 0xE0042000 // Debug MCU registers base address +#define SCS_BASE 0xE000E000 // System Control Space base +#define SCB (SCS_BASE + 0x0D00) // System Control Block base +#define NVIC (SCS_BASE + 0x0100) // Nested Interrupt Vector Controller base +#define OB_CTRL 0x1FF80000 // FLASH Option Bytes base address +#define AES_BASE 0x50060000 // Encryption module +#define FSMC_BASE 0xA0000000 // External Memory Control base +#define DBGMCU_BASE 0xE0042000 // Debug MCU registers base address +#define INFO_BASE (0x1ff00000U) // ----------------------------- Peripherals ---------------------------------- // *** Peripheral bus bases *** -#define _APB1 PERIPH_BASE // Advanced Peripheral Bus 1 base -#define _APB2 (PERIPH_BASE + 0x10000) // Advanced Peripheral Bus 2 base -#define _AHB (PERIPH_BASE + 0x20000) // Advanced High-speed Bus base +#define APB1_BASE PERIPH_BASE // Advanced Peripheral Bus 1 base +#define APB2_BASE (PERIPH_BASE + 0x10000) // Advanced Peripheral Bus 2 base +#define AHB_BASE (PERIPH_BASE + 0x20000) // Advanced High-speed Bus base // *** Peripheral Bus 1 devices *** -#define _TIM2 (_APB1 + 0x0000) // Timer bases -#define _TIM3 (_APB1 + 0x0400) -#define _TIM4 (_APB1 + 0x0800) -#define _TIM5 (_APB1 + 0x0C00) -#define _TIM6 (_APB1 + 0x1000) -#define _TIM7 (_APB1 + 0x1400) +#define TIM2 (APB1_BASE + 0x0000) // Timer bases +#define TIM3 (APB1_BASE + 0x0400) +#define TIM4 (APB1_BASE + 0x0800) +#define TIM5 (APB1_BASE + 0x0C00) +#define TIM6 (APB1_BASE + 0x1000) +#define TIM7 (APB1_BASE + 0x1400) -#define _LCD (_APB1 + 0x2400) // LCD controller base -#define _RTC (_APB1 + 0x2800) // RTC base +#define LCD (APB1_BASE + 0x2400) // LCD controller base +#define RTC (APB1_BASE + 0x2800) // RTC base -#define _WWDG (_APB1 + 0x2C00) // Window Watchdog base -#define _IWDG (_APB1 + 0x3000) // Independent Watchdog base +#define WWDG (APB1_BASE + 0x2C00) // Window Watchdog base +#define IWDG (APB1_BASE + 0x3000) // Independent Watchdog base -#define _SPI2 (_APB1 + 0x3800) // SPI base -#define _SPI3 (_APB1 + 0x3C00) +#define SPI2 (APB1_BASE + 0x3800) // SPI base +#define SPI3 (APB1_BASE + 0x3C00) -#define _USART2 (_APB1 + 0x4400) // USART base -#define _USART3 (_APB1 + 0x4800) +#define USART2 (APB1_BASE + 0x4400) // USART base +#define USART3 (APB1_BASE + 0x4800) -#define _UART4 (_APB1 + 0x4C00) // UART base (?) -#define _UART5 (_APB1 + 0x5000) +#define UART4 (APB1_BASE + 0x4C00) // UART base (?) +#define UART5 (APB1_BASE + 0x5000) -#define _I2C1 (_APB1 + 0x5400) // I2C base -#define _I2C2 (_APB1 + 0x5800) +#define I2C1 (APB1_BASE + 0x5400) // I2C base +#define I2C2 (APB1_BASE + 0x5800) -#define _PWR (_APB1 + 0x7000) // Power Control block base -#define _DAC (_APB1 + 0x7400) // D/A config base -#define _COMP (_APB1 + 0x7C00) // Analog Comparator base -#define _RI (_APB1 + 0x7C04) // Routing Interface base (analog pin connections) -#define _OPAMP (_APB1 + 0x7C5C) // OpAmp config base +#define PWR_CTRL (APB1_BASE + 0x7000) // Power Control block base +#define DAC_BASE (APB1_BASE + 0x7400) // D/A config base +#define COMP_BASE (APB1_BASE + 0x7C00) // Analog Comparator base +#define RI_BASE (APB1_BASE + 0x7C04) // Routing Interface base (analog pin connections) +#define OPAMP_BASE (APB1_BASE + 0x7C5C) // OpAmp config base -#define _USB (_APB1 + 0x5C00) // USB registers base +#define USB_BASE (APB1_BASE + 0x5C00) // USB registers base // *** Peripheral Bus 2 devices *** -#define _TIM9 (_APB2 + 0x0800) // Timer base -#define _TIM10 (_APB2 + 0x0C00) -#define _TIM11 (_APB2 + 0x1000) +#define TIM9 (APB2_BASE + 0x0800) // Timer base +#define TIM10 (APB2_BASE + 0x0C00) +#define TIM11 (APB2_BASE + 0x1000) -#define _SYSCFG (_APB2 + 0x0000) // System config block base -#define _EXTI (_APB2 + 0x0400) // External interrupt settings base +#define SYSCFG_BASE (APB2_BASE + 0x0000) // System config block base +#define EXTI_BASE (APB2_BASE + 0x0400) // External interrupt settings base -#define _ADC1 (_APB2 + 0x2400) // A/D 1 -#define _ADCC (_APB2 + 0x2700) // common A/D registers base +#define ADC1 (APB2_BASE + 0x2400) // A/D 1 +#define ADCC (APB2_BASE + 0x2700) // common A/D registers base -#define _SDIO (_APB2 + 0x2C00) // SD host -#define _SPI1 (_APB2 + 0x3000) // SPI -#define _USART1 (_APB2 + 0x3800) +#define SDIO (APB2_BASE + 0x2C00) // SD host +#define SPI1 (APB2_BASE + 0x3000) // SPI +#define USART1 (APB2_BASE + 0x3800) // *** High Speed Bus devices *** -#define _GPIO (_AHB + 0x0000) // GPIO block base +#define GPIO_BASE (AHB_BASE + 0x0000) // GPIO block base -#define _CRC (_AHB + 0x3000) // CRC module base -#define _RCC (_AHB + 0x3800) // Reset and Clock Config base +#define CRC_BASE (AHB_BASE + 0x3000) // CRC module base +#define RCC_BASE (AHB_BASE + 0x3800) // Reset and Clock Config base -#define _DMA1 (_AHB + 0x6000) // DMA control base -#define _DMA2 (_AHB + 0x6400) +#define DMA1 (AHB_BASE + 0x6000) // DMA control base +#define DMA2 (AHB_BASE + 0x6400) -#define _FLASH (_AHB + 0x3C00) // FLASH control base +#define FLASH_CTRL (AHB_BASE + 0x3C00) // FLASH control base + + +/* MPU: Memory protection unit */ +#define MPU_BASE (SCS_BASE + 0x0D90) + +// ---- + +/* Device Electronic Signature */ +#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x8004C) +#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x80050) +#define DESIG_UNIQUE_ID0 MMIO32(DESIG_UNIQUE_ID_BASE) +#define DESIG_UNIQUE_ID1 MMIO32(DESIG_UNIQUE_ID_BASE + 4) +#define DESIG_UNIQUE_ID2 MMIO32(DESIG_UNIQUE_ID_BASE + 0x14) + +/* ST provided factory calibration values @ 3.0V */ +#define ST_VREFINT_CAL MMIO16(0x1FF80078) +#define ST_TSENSE_CAL1_30C MMIO16(0x1FF8007A) +#define ST_TSENSE_CAL2_110C MMIO16(0x1FF8007E) + + +// ---- ARMv7M+ only ---- + +#define PPBI_BASE (0xE0000000U) + +/* STE: Software Trigger Interrupt Register */ +#define STIR_BASE (SCS_BASE + 0x0F00) +/* ID: ID space */ +#define ID_BASE (SCS_BASE + 0x0FD0) +/* ITR: Interrupt Type Register */ +#define ITR_BASE (SCS_BASE + 0x0000) + +/* ITM: Instrumentation Trace Macrocell */ +#define ITM_BASE (PPBI_BASE + 0x0000) + +/* DWT: Data Watchpoint and Trace unit */ +#define DWT_BASE (PPBI_BASE + 0x1000) + +/* FPB: Flash Patch and Breakpoint unit */ +#define FPB_BASE (PPBI_BASE + 0x2000) + +#define TPIU_BASE (PPBI_BASE + 0x40000) diff --git a/lib/defs_flash.h b/lib/defs_flash.h index fd8e5ad..7f674eb 100644 --- a/lib/defs_flash.h +++ b/lib/defs_flash.h @@ -18,28 +18,28 @@ // FLASH registers -#define FLASH_ACR MMIO32(_FLASH + 0x00) // Access control register, -#define FLASH_PECR MMIO32(_FLASH + 0x04) // Program/erase control register, -#define FLASH_PDKEYR MMIO32(_FLASH + 0x08) // Power down key register, -#define FLASH_PEKEYR MMIO32(_FLASH + 0x0c) // Program/erase key register, -#define FLASH_PRGKEYR MMIO32(_FLASH + 0x10) // Program memory key register, -#define FLASH_OPTKEYR MMIO32(_FLASH + 0x14) // Option byte key register, -#define FLASH_SR MMIO32(_FLASH + 0x18) // Status register, -#define FLASH_OBR MMIO32(_FLASH + 0x1c) // Option byte register, -#define FLASH_WRPR MMIO32(_FLASH + 0x20) // Write protection register, -#define FLASH_WRPR1 MMIO32(_FLASH + 0x28) // Write protection register 1, -#define FLASH_WRPR2 MMIO32(_FLASH + 0x2C) // Write protection register 2, +#define FLASH_ACR MMIO32(FLASH_CTRL + 0x00) // Access control register, +#define FLASH_PECR MMIO32(FLASH_CTRL + 0x04) // Program/erase control register, +#define FLASH_PDKEYR MMIO32(FLASH_CTRL + 0x08) // Power down key register, +#define FLASH_PEKEYR MMIO32(FLASH_CTRL + 0x0c) // Program/erase key register, +#define FLASH_PRGKEYR MMIO32(FLASH_CTRL + 0x10) // Program memory key register, +#define FLASH_OPTKEYR MMIO32(FLASH_CTRL + 0x14) // Option byte key register, +#define FLASH_SR MMIO32(FLASH_CTRL + 0x18) // Status register, +#define FLASH_OBR MMIO32(FLASH_CTRL + 0x1c) // Option byte register, +#define FLASH_WRPR MMIO32(FLASH_CTRL + 0x20) // Write protection register, +#define FLASH_WRPR1 MMIO32(FLASH_CTRL + 0x28) // Write protection register 1, +#define FLASH_WRPR2 MMIO32(FLASH_CTRL + 0x2C) // Write protection register 2, // FLASH option bytes (maybe incorrect, not tested) -#define OB_RDP MMIO32(_OB + 0x00) // Read protection register, -#define OB_USER MMIO32(_OB + 0x04) // user register, -#define OB_WRP01 MMIO32(_OB + 0x08) // write protection register 0 1, -#define OB_WRP23 MMIO32(_OB + 0x0C) // write protection register 2 3, -#define OB_WRP45 MMIO32(_OB + 0x10) // write protection register 4 5, -#define OB_WRP67 MMIO32(_OB + 0x14) // write protection register 6 7, -#define OB_WRP89 MMIO32(_OB + 0x18) // write protection register 8 9, -#define OB_WRP1011 MMIO32(_OB + 0x1C) // write protection register 10 11, +#define OB_RDP MMIO32(OB_CTRL + 0x00) // Read protection register, +#define OB_USER MMIO32(OB_CTRL + 0x04) // user register, +#define OB_WRP01 MMIO32(OB_CTRL + 0x08) // write protection register 0 1, +#define OB_WRP23 MMIO32(OB_CTRL + 0x0C) // write protection register 2 3, +#define OB_WRP45 MMIO32(OB_CTRL + 0x10) // write protection register 4 5, +#define OB_WRP67 MMIO32(OB_CTRL + 0x14) // write protection register 6 7, +#define OB_WRP89 MMIO32(OB_CTRL + 0x18) // write protection register 8 9, +#define OB_WRP1011 MMIO32(OB_CTRL + 0x1C) // write protection register 10 11, diff --git a/lib/defs_gpio.h b/lib/defs_gpio.h index 2f348f4..66900d0 100644 --- a/lib/defs_gpio.h +++ b/lib/defs_gpio.h @@ -8,25 +8,26 @@ // offsets -#define GPIO_MODER_offs 0x00 // GPIOA pin mode register, -#define GPIO_OTYPER_offs 0x04 // GPIOA output type register, -#define GPIO_OSPEEDR_offs 0x08 // GPIOA output speed register, -#define GPIO_PUPDR_offs 0x0C // GPIOA pull-up/pull-down register, -#define GPIO_IDR_offs 0x10 // GPIOA input data register, -#define GPIO_ODR_offs 0x14 // GPIOA output data register, -#define GPIO_BSRR_offs 0x18 // GPIOA bit set/reset register, -#define GPIO_LCKR_offs 0x1C // GPIOA configuration lock register, -#define GPIO_AFR_offs 0x20 // GPIOA alternate function register, -#define GPIO_BRR_offs 0x28 // GPIOA bit reset register, +#define GPIO_MODER_offs 0x00 // GPIO pin mode register, +#define GPIO_OTYPER_offs 0x04 // GPIO output type register, +#define GPIO_OSPEEDR_offs 0x08 // GPIO output speed register, +#define GPIO_PUPDR_offs 0x0C // GPIO pull-up/pull-down register, +#define GPIO_IDR_offs 0x10 // GPIO input data register, +#define GPIO_ODR_offs 0x14 // GPIO output data register, +#define GPIO_BSRR_offs 0x18 // GPIO bit set/reset register, +#define GPIO_LCKR_offs 0x1C // GPIO configuration lock register, +#define GPIO_AFRL_offs 0x20 // GPIO alternate function register, +#define GPIO_AFRH_offs 0x24 // GPIO alternate function register, +#define GPIO_BRR_offs 0x28 // GPIO bit reset register, -#define GPIOA (_GPIO + 0x0000) -#define GPIOB (_GPIO + 0x0400) -#define GPIOC (_GPIO + 0x0800) -#define GPIOD (_GPIO + 0x0C00) -#define GPIOE (_GPIO + 0x1000) -#define GPIOH (_GPIO + 0x1400) -#define GPIOF (_GPIO + 0x1800) -#define GPIOG (_GPIO + 0x1C00) +#define GPIOA (GPIO_BASE + 0x0000) +#define GPIOB (GPIO_BASE + 0x0400) +#define GPIOC (GPIO_BASE + 0x0800) +#define GPIOD (GPIO_BASE + 0x0C00) +#define GPIOE (GPIO_BASE + 0x1000) +#define GPIOH (GPIO_BASE + 0x1400) +#define GPIOF (GPIO_BASE + 0x1800) +#define GPIOG (GPIO_BASE + 0x1C00) #define GPIOA_MODER MMIO32(GPIOA + 0x00) // GPIOA pin mode register, #define GPIOA_OTYPER MMIO32(GPIOA + 0x04) // GPIOA output type register, @@ -36,7 +37,8 @@ #define GPIOA_ODR MMIO32(GPIOA + 0x14) // GPIOA output data register, #define GPIOA_BSRR MMIO32(GPIOA + 0x18) // GPIOA bit set/reset register, #define GPIOA_LCKR MMIO32(GPIOA + 0x1C) // GPIOA configuration lock register, -#define GPIOA_AFR MMIO64(GPIOA + 0x20) // GPIOA alternate function register, +#define GPIOA_AFRL MMIO32(GPIOA + 0x20) // GPIOA alternate function register, +#define GPIOA_AFRH MMIO32(GPIOA + 0x24) // GPIOA alternate function register, #define GPIOA_BRR MMIO32(GPIOA + 0x28) // GPIOA bit reset register, #define GPIOB_MODER MMIO32(GPIOB + 0x00) // GPIOB pin mode register, @@ -47,7 +49,8 @@ #define GPIOB_ODR MMIO32(GPIOB + 0x14) // GPIOB output data register, #define GPIOB_BSRR MMIO32(GPIOB + 0x18) // GPIOB bit set/reset register, #define GPIOB_LCKR MMIO32(GPIOB + 0x1C) // GPIOB configuration lock register, -#define GPIOB_AFR MMIO64(GPIOB + 0x20) // GPIOB alternate function low register, +#define GPIOB_AFRL MMIO32(GPIOB + 0x20) // GPIOB alternate function register, +#define GPIOB_AFRH MMIO32(GPIOB + 0x24) // GPIOB alternate function register, #define GPIOB_BRR MMIO32(GPIOB + 0x28) // GPIOB bit reset register, #define GPIOC_MODER MMIO32(GPIOC + 0x00) // GPIOC pin mode register, @@ -58,7 +61,8 @@ #define GPIOC_ODR MMIO32(GPIOC + 0x14) // GPIOC output data register, #define GPIOC_BSRR MMIO32(GPIOC + 0x18) // GPIOC bit set/reset register, #define GPIOC_LCKR MMIO32(GPIOC + 0x1C) // GPIOC configuration lock register, -#define GPIOC_AFR MMIO64(GPIOC + 0x20) // GPIOC alternate function low register, +#define GPIOC_AFRL MMIO32(GPIOC + 0x20) // GPIOC alternate function register, +#define GPIOC_AFRH MMIO32(GPIOC + 0x24) // GPIOC alternate function register, #define GPIOC_BRR MMIO32(GPIOC + 0x28) // GPIOC bit reset register, #define GPIOD_MODER MMIO32(GPIOD + 0x00) // GPIOD pin mode register, @@ -69,7 +73,8 @@ #define GPIOD_ODR MMIO32(GPIOD + 0x14) // GPIOD output data register, #define GPIOD_BSRR MMIO32(GPIOD + 0x18) // GPIOD bit set/reset register, #define GPIOD_LCKR MMIO32(GPIOD + 0x1C) // GPIOD configuration lock register, -#define GPIOD_AFR MMIO64(GPIOD + 0x20) // GPIOD alternate function low register, +#define GPIOD_AFRL MMIO32(GPIOD + 0x20) // GPIOD alternate function register, +#define GPIOD_AFRH MMIO32(GPIOD + 0x24) // GPIOD alternate function register, #define GPIOD_BRR MMIO32(GPIOD + 0x28) // GPIOD bit reset register, #define GPIOE_MODER MMIO32(GPIOE + 0x00) // GPIOE pin mode register, @@ -80,7 +85,8 @@ #define GPIOE_ODR MMIO32(GPIOE + 0x14) // GPIOE output data register, #define GPIOE_BSRR MMIO32(GPIOE + 0x18) // GPIOE bit set/reset register, #define GPIOE_LCKR MMIO32(GPIOE + 0x1C) // GPIOE configuration lock register, -#define GPIOE_AFR MMIO64(GPIOE + 0x20) // GPIOE alternate function low register, +#define GPIOE_AFRL MMIO32(GPIOE + 0x20) // GPIOE alternate function register, +#define GPIOE_AFRH MMIO32(GPIOE + 0x24) // GPIOE alternate function register, #define GPIOE_BRR MMIO32(GPIOE + 0x28) // GPIOE bit reset register, #define GPIOF_MODER MMIO32(GPIOF + 0x00) // GPIOF pin mode register, @@ -91,7 +97,8 @@ #define GPIOF_ODR MMIO32(GPIOF + 0x14) // GPIOF output data register, #define GPIOF_BSRR MMIO32(GPIOF + 0x18) // GPIOF bit set/reset register, #define GPIOF_LCKR MMIO32(GPIOF + 0x1C) // GPIOF configuration lock register, -#define GPIOF_AFR MMIO64(GPIOF + 0x20) // GPIOF alternate function low register, +#define GPIOF_AFRL MMIO32(GPIOF + 0x20) // GPIOF alternate function register, +#define GPIOF_AFRH MMIO32(GPIOF + 0x24) // GPIOF alternate function register, #define GPIOF_BRR MMIO32(GPIOF + 0x28) // GPIOF bit reset register, #define GPIOG_MODER MMIO32(GPIOG + 0x00) // GPIOG pin mode register, @@ -102,7 +109,8 @@ #define GPIOG_ODR MMIO32(GPIOG + 0x14) // GPIOG output data register, #define GPIOG_BSRR MMIO32(GPIOG + 0x18) // GPIOG bit set/reset register, #define GPIOG_LCKR MMIO32(GPIOG + 0x1C) // GPIOG configuration lock register, -#define GPIOG_AFR MMIO64(GPIOG + 0x20) // GPIOG alternate function low register, +#define GPIOG_AFRL MMIO32(GPIOG + 0x20) // GPIOG alternate function register, +#define GPIOG_AFRH MMIO32(GPIOG + 0x24) // GPIOG alternate function register, #define GPIOG_BRR MMIO32(GPIOG + 0x28) // GPIOG bit reset register, #define GPIOH_MODER MMIO32(GPIOH + 0x00) // GPIOH pin mode register, @@ -113,5 +121,6 @@ #define GPIOH_ODR MMIO32(GPIOH + 0x14) // GPIOH output data register, #define GPIOH_BSRR MMIO32(GPIOH + 0x18) // GPIOH bit set/reset register, #define GPIOH_LCKR MMIO32(GPIOH + 0x1C) // GPIOH configuration lock register, -#define GPIOH_AFR MMIO64(GPIOH + 0x20) // GPIOH alternate function low register, +#define GPIOH_AFRL MMIO32(GPIOH + 0x20) // GPIOH alternate function register, +#define GPIOH_AFRH MMIO32(GPIOH + 0x24) // GPIOH alternate function register, #define GPIOH_BRR MMIO32(GPIOH + 0x28) // GPIOH bit reset register, diff --git a/lib/defs_rcc.h b/lib/defs_rcc.h index 4c96ab4..d1ff309 100644 --- a/lib/defs_rcc.h +++ b/lib/defs_rcc.h @@ -4,20 +4,20 @@ // RCC registers -#define RCC_CR MMIO32(_RCC + 0x00) // RCC clock control register, -#define RCC_ICSCR MMIO32(_RCC + 0x04) // RCC Internal clock sources calibration register, -#define RCC_CFGR MMIO32(_RCC + 0x08) // RCC Clock configuration register, -#define RCC_CIR MMIO32(_RCC + 0x0C) // RCC Clock interrupt register, -#define RCC_AHBRSTR MMIO32(_RCC + 0x10) // RCC AHB peripheral reset register, -#define RCC_APB2RSTR MMIO32(_RCC + 0x14) // RCC APB2 peripheral reset register, -#define RCC_APB1RSTR MMIO32(_RCC + 0x18) // RCC APB1 peripheral reset register, -#define RCC_AHBENR MMIO32(_RCC + 0x1C) // RCC AHB peripheral clock enable register, -#define RCC_APB2ENR MMIO32(_RCC + 0x20) // RCC APB2 peripheral clock enable register, -#define RCC_APB1ENR MMIO32(_RCC + 0x24) // RCC APB1 peripheral clock enable register, -#define RCC_AHBLPENR MMIO32(_RCC + 0x28) // RCC AHB peripheral clock enable in low power mode register, -#define RCC_APB2LPENR MMIO32(_RCC + 0x2C) // RCC APB2 peripheral clock enable in low power mode register, -#define RCC_APB1LPENR MMIO32(_RCC + 0x30) // RCC APB1 peripheral clock enable in low power mode register, -#define RCC_CSR MMIO32(_RCC + 0x34) // RCC Control/status register, +#define RCC_CR MMIO32(RCC_BASE + 0x00) // RCC clock control register, +#define RCC_ICSCR MMIO32(RCC_BASE + 0x04) // RCC Internal clock sources calibration register, +#define RCC_CFGR MMIO32(RCC_BASE + 0x08) // RCC Clock configuration register, +#define RCC_CIR MMIO32(RCC_BASE + 0x0C) // RCC Clock interrupt register, +#define RCC_AHBRSTR MMIO32(RCC_BASE + 0x10) // RCC AHB peripheral reset register, +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x14) // RCC APB2 peripheral reset register, +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x18) // RCC APB1 peripheral reset register, +#define RCC_AHBENR MMIO32(RCC_BASE + 0x1C) // RCC AHB peripheral clock enable register, +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x20) // RCC APB2 peripheral clock enable register, +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x24) // RCC APB1 peripheral clock enable register, +#define RCC_AHBLPENR MMIO32(RCC_BASE + 0x28) // RCC AHB peripheral clock enable in low power mode register, +#define RCC_APB2LPENR MMIO32(RCC_BASE + 0x2C) // RCC APB2 peripheral clock enable in low power mode register, +#define RCC_APB1LPENR MMIO32(RCC_BASE + 0x30) // RCC APB1 peripheral clock enable in low power mode register, +#define RCC_CSR MMIO32(RCC_BASE + 0x34) // RCC Control/status register, diff --git a/lib/defs_systick.h b/lib/defs_systick.h index 96ede98..0b7c3df 100644 --- a/lib/defs_systick.h +++ b/lib/defs_systick.h @@ -14,10 +14,10 @@ //**************************************************************************** -#define SysTick_CSR MMIO32(_SCS_BASE + 0x010) // (R/W) SysTick Control and Status Register -#define SysTick_RELOAD MMIO32(_SCS_BASE + 0x014) // (R/W) SysTick Reload Value Register -#define SysTick_VAL MMIO32(_SCS_BASE + 0x018) // (R/W) SysTick Current Value Register -#define SysTick_CALIB MMIO32(_SCS_BASE + 0x01C) // (R/ ) SysTick Calibration Value Register +#define SysTick_CSR MMIO32(SCS_BASE + 0x010) // (R/W) SysTick Control and Status Register +#define SysTick_RELOAD MMIO32(SCS_BASE + 0x014) // (R/W) SysTick Reload Value Register +#define SysTick_VAL MMIO32(SCS_BASE + 0x018) // (R/W) SysTick Current Value Register +#define SysTick_CALIB MMIO32(SCS_BASE + 0x01C) // (R/ ) SysTick Calibration Value Register diff --git a/lib/defs_usart.h b/lib/defs_usart.h index 2437808..0f78b52 100644 --- a/lib/defs_usart.h +++ b/lib/defs_usart.h @@ -11,55 +11,65 @@ //* //**************************************************************************** +// offsets +#define USART_SR_offs 0x00 // USART1 Status register, +#define USART_DR_offs 0x04 // USART1 Data register, +#define USART_BRR_offs 0x08 // USART1 Baud rate register, +#define USART_CR1_offs 0x0C // USART1 Control register 1, +#define USART_CR2_offs 0x10 // USART1 Control register 2, +#define USART_CR3_offs 0x14 // USART1 Control register 3, +#define USART_GTPR_offs 0x18 // USART1 Guard time and prescaler register, + + // USART 1 -#define USART1_SR MMIO32(_USART1 + 0x00) // USART1 Status register, -#define USART1_DR MMIO32(_USART1 + 0x04) // USART1 Data register, -#define USART1_BRR MMIO32(_USART1 + 0x08) // USART1 Baud rate register, -#define USART1_CR1 MMIO32(_USART1 + 0x0C) // USART1 Control register 1, -#define USART1_CR2 MMIO32(_USART1 + 0x10) // USART1 Control register 2, -#define USART1_CR3 MMIO32(_USART1 + 0x14) // USART1 Control register 3, -#define USART1_GTPR MMIO32(_USART1 + 0x18) // USART1 Guard time and prescaler register, +#define USART1_SR MMIO32(USART1 + 0x00) // USART1 Status register, +#define USART1_DR MMIO32(USART1 + 0x04) // USART1 Data register, +#define USART1_BRR MMIO32(USART1 + 0x08) // USART1 Baud rate register, +#define USART1_CR1 MMIO32(USART1 + 0x0C) // USART1 Control register 1, +#define USART1_CR2 MMIO32(USART1 + 0x10) // USART1 Control register 2, +#define USART1_CR3 MMIO32(USART1 + 0x14) // USART1 Control register 3, +#define USART1_GTPR MMIO32(USART1 + 0x18) // USART1 Guard time and prescaler register, // USART 2 -#define USART2_SR MMIO32(_USART2 + 0x00) // USART2 Status register, -#define USART2_DR MMIO32(_USART2 + 0x04) // USART2 Data register, -#define USART2_BRR MMIO32(_USART2 + 0x08) // USART2 Baud rate register, -#define USART2_CR1 MMIO32(_USART2 + 0x0C) // USART2 Control register 1, -#define USART2_CR2 MMIO32(_USART2 + 0x10) // USART2 Control register 2, -#define USART2_CR3 MMIO32(_USART2 + 0x14) // USART2 Control register 3, -#define USART2_GTPR MMIO32(_USART2 + 0x18) // USART2 Guard time and prescaler register, +#define USART2_SR MMIO32(USART2 + 0x00) // USART2 Status register, +#define USART2_DR MMIO32(USART2 + 0x04) // USART2 Data register, +#define USART2_BRR MMIO32(USART2 + 0x08) // USART2 Baud rate register, +#define USART2_CR1 MMIO32(USART2 + 0x0C) // USART2 Control register 1, +#define USART2_CR2 MMIO32(USART2 + 0x10) // USART2 Control register 2, +#define USART2_CR3 MMIO32(USART2 + 0x14) // USART2 Control register 3, +#define USART2_GTPR MMIO32(USART2 + 0x18) // USART2 Guard time and prescaler register, // USART 3 -#define USART3_SR MMIO32(_USART3 + 0x00) // USART3 Status register, -#define USART3_DR MMIO32(_USART3 + 0x04) // USART3 Data register, -#define USART3_BRR MMIO32(_USART3 + 0x08) // USART3 Baud rate register, -#define USART3_CR1 MMIO32(_USART3 + 0x0C) // USART3 Control register 1, -#define USART3_CR2 MMIO32(_USART3 + 0x10) // USART3 Control register 2, -#define USART3_CR3 MMIO32(_USART3 + 0x14) // USART3 Control register 3, -#define USART3_GTPR MMIO32(_USART3 + 0x18) // USART3 Guard time and prescaler register, +#define USART3_SR MMIO32(USART3 + 0x00) // USART3 Status register, +#define USART3_DR MMIO32(USART3 + 0x04) // USART3 Data register, +#define USART3_BRR MMIO32(USART3 + 0x08) // USART3 Baud rate register, +#define USART3_CR1 MMIO32(USART3 + 0x0C) // USART3 Control register 1, +#define USART3_CR2 MMIO32(USART3 + 0x10) // USART3 Control register 2, +#define USART3_CR3 MMIO32(USART3 + 0x14) // USART3 Control register 3, +#define USART3_GTPR MMIO32(USART3 + 0x18) // USART3 Guard time and prescaler register, // USART 4 -#define UART4_SR MMIO32(_UART4 + 0x00) // UART4 Status register, -#define UART4_DR MMIO32(_UART4 + 0x04) // UART4 Data register, -#define UART4_BRR MMIO32(_UART4 + 0x08) // UART4 Baud rate register, -#define UART4_CR1 MMIO32(_UART4 + 0x0C) // UART4 Control register 1, -#define UART4_CR2 MMIO32(_UART4 + 0x10) // UART4 Control register 2, -#define UART4_CR3 MMIO32(_UART4 + 0x14) // UART4 Control register 3, -#define UART4_GTPR MMIO32(_UART4 + 0x18) // UART4 Guard time and prescaler register, +#define UART4_SR MMIO32(UART4 + 0x00) // UART4 Status register, +#define UART4_DR MMIO32(UART4 + 0x04) // UART4 Data register, +#define UART4_BRR MMIO32(UART4 + 0x08) // UART4 Baud rate register, +#define UART4_CR1 MMIO32(UART4 + 0x0C) // UART4 Control register 1, +#define UART4_CR2 MMIO32(UART4 + 0x10) // UART4 Control register 2, +#define UART4_CR3 MMIO32(UART4 + 0x14) // UART4 Control register 3, +#define UART4_GTPR MMIO32(UART4 + 0x18) // UART4 Guard time and prescaler register, // USART 5 -#define UART5_SR MMIO32(_UART5 + 0x00) // UART5 Status register, -#define UART5_DR MMIO32(_UART5 + 0x04) // UART5 Data register, -#define UART5_BRR MMIO32(_UART5 + 0x08) // UART5 Baud rate register, -#define UART5_CR1 MMIO32(_UART5 + 0x0C) // UART5 Control register 1, -#define UART5_CR2 MMIO32(_UART5 + 0x10) // UART5 Control register 2, -#define UART5_CR3 MMIO32(_UART5 + 0x14) // UART5 Control register 3, -#define UART5_GTPR MMIO32(_UART5 + 0x18) // UART5 Guard time and prescaler register, +#define UART5_SR MMIO32(UART5 + 0x00) // UART5 Status register, +#define UART5_DR MMIO32(UART5 + 0x04) // UART5 Data register, +#define UART5_BRR MMIO32(UART5 + 0x08) // UART5 Baud rate register, +#define UART5_CR1 MMIO32(UART5 + 0x0C) // UART5 Control register 1, +#define UART5_CR2 MMIO32(UART5 + 0x10) // UART5 Control register 2, +#define UART5_CR3 MMIO32(UART5 + 0x14) // UART5 Control register 3, +#define UART5_GTPR MMIO32(UART5 + 0x18) // UART5 Guard time and prescaler register, diff --git a/lib/gpio.c b/lib/gpio.c index 2d0be0c..236e4ae 100644 --- a/lib/gpio.c +++ b/lib/gpio.c @@ -4,15 +4,24 @@ static uint32_t rcc_gpio_mask(uint32_t gpio) { switch (gpio) { - case GPIOA: return RCC_AHBENR_GPIOAEN; - case GPIOB: return RCC_AHBENR_GPIOBEN; - case GPIOC: return RCC_AHBENR_GPIOCEN; - case GPIOD: return RCC_AHBENR_GPIODEN; - case GPIOE: return RCC_AHBENR_GPIOEEN; - case GPIOF: return RCC_AHBENR_GPIOFEN; - case GPIOG: return RCC_AHBENR_GPIOGEN; - case GPIOH: return RCC_AHBENR_GPIOHEN; - default: return 0; + case GPIOA: + return RCC_AHBENR_GPIOAEN; + case GPIOB: + return RCC_AHBENR_GPIOBEN; + case GPIOC: + return RCC_AHBENR_GPIOCEN; + case GPIOD: + return RCC_AHBENR_GPIODEN; + case GPIOE: + return RCC_AHBENR_GPIOEEN; + case GPIOF: + return RCC_AHBENR_GPIOFEN; + case GPIOG: + return RCC_AHBENR_GPIOGEN; + case GPIOH: + return RCC_AHBENR_GPIOHEN; + default: + return 0; } } @@ -33,16 +42,23 @@ void gpio_set_af(uint32_t gpio, uint32_t pins, enum GPIO_AF af) { gpio_enable(gpio); - volatile uint32_t *moder = (uint32_t *) gpio + GPIO_MODER_offs; - volatile uint64_t *afr = (uint64_t *) gpio + GPIO_AFR_offs; + io32_t moder = P_REG(gpio, GPIO_MODER_offs); + io32_t afrl = P_REG(gpio, GPIO_AFRL_offs); + io32_t afrh = P_REG(gpio, GPIO_AFRH_offs); BitFieldLoop(i, m, 16) { if (pins & m) { + // set pin mode to AF *moder &= ~(0b11 << i * 2); - *moder |= 0b10 << i * 2; + *moder |= MODER_AF << i * 2; - *afr &= ~(0xF << i * 4); - *afr |= af << i * 4; + if (i < 8) { + *afrl &= ~(0xF << i * 4); + *afrl |= af << i * 4; + } else { + *afrh &= ~(0xF << (i - 8) * 4); + *afrh |= af << (i - 8) * 4; + } } }; } @@ -50,7 +66,7 @@ void gpio_set_af(uint32_t gpio, uint32_t pins, enum GPIO_AF af) void gpio_set_mode(uint32_t gpio, uint32_t pins, enum GPIO_MODE mode) { - volatile uint32_t *moder = (uint32_t *) gpio + GPIO_MODER_offs; + io32_t moder = P_REG(gpio, GPIO_MODER_offs); BitFieldLoop(i, m, 16) { if (pins & m) { diff --git a/lib/usart.c b/lib/usart.c new file mode 100644 index 0000000..ad2522b --- /dev/null +++ b/lib/usart.c @@ -0,0 +1,84 @@ +#include "usart.h" + +#define RX_TIMEOUT 1000000 +#define TX_TIMEOUT 1000000 + + +/** Wait for incoming data on USART (true on success) */ +bool usart_wait_rx(uint32_t usart) +{ + for (uint32_t i = 0; i < RX_TIMEOUT; i++) { + if (usart_rx_ready(usart)) return true; + } + return false; +} + + +/** Wait for outgoing data on USART (true on success) */ +bool usart_wait_tx(uint32_t usart) +{ + for (uint32_t i = 0; i < TX_TIMEOUT; i++) { + if (usart_tx_ready(usart)) return true; + } + return false; +} + + +/** Check if USART has received a byte */ +bool usart_rx_ready(uint32_t usart) +{ + io32_t SR = P_REG(usart, USART_SR_offs); + + return (*SR & USART_SR_RXNE); +} + + +/** Check if USART has finished sending a byte */ +bool usart_tx_ready(uint32_t usart) +{ + io32_t SR = P_REG(usart, USART_SR_offs); + + return (*SR & USART_SR_TXE); +} + + +/** Receive a char from USART. Does not check if ready. */ +char usart_rx_char(uint32_t usart) +{ + io32_t DR = P_REG(usart, USART_DR_offs); + + return *DR & 0xFF; +} + + +/** Receive up to `len` chars from USART. */ +uint32_t usart_rx_string(uint32_t usart, char *buffer, uint32_t len) +{ + uint32_t i; + for (i = 0; i < len; i++) { + if (!usart_wait_rx(usart)) break; + buffer[i] = usart_rx_char(usart); + } + + buffer[i] = 0; + return i; +} + + +/** Transmit a character. First waits for TX buffer to empty. */ +void usart_tx_char(uint32_t usart, uint8_t c) +{ + io32_t DR = P_REG(usart, USART_DR_offs); + usart_wait_tx(usart); + *DR = c; +} + +/** Transmit a string until \0 */ +void usart_tx_string(uint32_t usart, char *string) +{ + char c; + while ((c = *string++) != 0) { + usart_tx_char(usart, c); + } +} + diff --git a/lib/usart.h b/lib/usart.h new file mode 100644 index 0000000..d26bd7e --- /dev/null +++ b/lib/usart.h @@ -0,0 +1,31 @@ +#pragma once +#include "common.h" + +/** Wait for incoming data on USART (true on success) */ +bool usart_wait_rx(uint32_t usart); + +/** Check if USART has received a byte */ +bool usart_rx_ready(uint32_t usart); + +/** Receive a char from USART. Does not check if ready. */ +char usart_rx_char(uint32_t usart); + +/** + * Receive up to `len` chars from USART; + * + * Adds \0 after last char. + * Total length (without the \0) is returned. + */ +uint32_t usart_rx_string(uint32_t usart, char *buffer, uint32_t len); + +/** Wait for outgoing data on USART (true on success) */ +bool usart_wait_tx(uint32_t usart); + +/** Check if USART has finished sending a byte */ +bool usart_tx_ready(uint32_t usart); + +/** Transmit a character. First waits for TX buffer to empty. */ +void usart_tx_char(uint32_t usart, uint8_t c); + +/** Transmit a string until \0 */ +void usart_tx_string(uint32_t usart, char *string); diff --git a/main.c b/main.c index ea8b9f6..2c8a79d 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,7 @@ #include #include #include +#include static void init_gpios(void) @@ -9,7 +10,9 @@ static void init_gpios(void) gpio_enable(GPIOB); gpio_enable(GPIOC); - gpio_set_mode(GPIOC, BIT8 | BIT9, MODER_OUTPUT); + gpio_set_mode(GPIOC, BIT8 | BIT9 | BIT7, MODER_OUTPUT); + + gpio_set_mode(GPIOA, BIT8, MODER_OUTPUT); } @@ -39,8 +42,8 @@ static void init_usart(void) RCC_APB1ENR |= RCC_APB1ENR_USART3EN; // RATE 9600Bd 104.1875 (see datasheet for reference)8.6875 - // 0x00683 ... 9600 - USART3_BRR = 0x0008A; // 115200 + //USART3_BRR = 0x00683; // 9600 + USART3_BRR = 0x0008A; // 115200 // USART enable USART3_CR1 = USART_CR1_UE | USART_CR1_RE | USART_CR1_TE; @@ -74,7 +77,7 @@ void SysTick_Handler(void) void delay(void) { - for (int i = 0; i < 100000; i++) { + for (int i = 0; i < 800000; i++) { __asm__("nop"); } } @@ -85,5 +88,7 @@ int main(void) while (1) { delay(); GPIOC_ODR ^= BIT8; + + usart_tx_string(USART3, "HELLO\r\n"); } } diff --git a/proj.pro b/proj.pro index f10b1f3..2248207 100644 --- a/proj.pro +++ b/proj.pro @@ -19,7 +19,8 @@ DISTFILES += \ SOURCES += \ main.c \ lib/gpio.c \ - lib/systick.c + lib/systick.c \ + lib/usart.c HEADERS += \ lib/common.h \ @@ -30,5 +31,6 @@ HEADERS += \ lib/gpio.h \ lib/defs_systick.h \ lib/systick.h \ - lib/defs_usart.h + lib/defs_usart.h \ + lib/usart.h