diff --git a/arduino_stm32f411.h b/arduino_stm32f411.h index 4f660b0..672eb0f 100644 --- a/arduino_stm32f411.h +++ b/arduino_stm32f411.h @@ -24,10 +24,8 @@ /** Pins for UART, the serial port. */ -#define RXD_PORT PA_3_PORT -#define RXD_PIN PA_3_PIN -#define TXD_PORT PA_2_PORT -#define TXD_PIN PA_2_PIN +#define RXD PA_3 +#define TXD PA_2 /** We define only pins available on the Nucleo F411RE here. diff --git a/heater-stm32.c b/heater-stm32.c index 9248c95..81aad6c 100644 --- a/heater-stm32.c +++ b/heater-stm32.c @@ -168,19 +168,10 @@ void heater_init() { else if (pin ## _TIMER == TIM4) { \ RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; } /* turn on TIM4 */ \ /* TIM5 is for stepper, TIM9, TIM10 and TIM11 are not used */ \ - pin ## _PORT->MODER &= ~(3 << (pin ## _PIN << 1)); /* reset pin mode */ \ - pin ## _PORT->MODER |= (2 << (pin ## _PIN << 1)); /* pin mode to AF */ \ - pin ## _PORT->OSPEEDR |= (3 << (pin ## _PIN << 1)); /* high speed */ \ - pin ## _PORT->PUPDR &= ~(3 << ((pin ## _PIN) << 1)); /* no pullup-pulldown */ \ - macro_mask = pin ## _PIN < 8 ? (pin ## _PIN) : (pin ## _PIN - 8); \ - /* we have to registers for AFR. ARF[0] for the first 8, ARF[1] for the second 8*/ \ - /* also we use this to keep the compiler happy and don't shift > 32 */ \ - if (pin ## _PIN < 8) { \ - pin ## _PORT->AFR[0] |= pin ## _AF << (macro_mask * 4); \ - } else { \ - pin ## _PORT->AFR[1] |= pin ## _AF << (macro_mask * 4); \ - } \ - /* AFR is a 64bit register, first half are for pin 0-7, second half 8-15 */ \ + SET_MODE(pin, 0x2); /* pin mode to AF */ \ + SET_AFR(pin, pin ## _AF); \ + SET_OSPEED(pin, 0x3); /* high speed */ \ + PULL_OFF(pin); /* no pullup/-down */ \ pin ## _TIMER->CR1 |= TIM_CR1_ARPE; /* auto-reload preload */ \ pin ## _TIMER->ARR = PWM_SCALE - 1; /* reset on auto reload at 254 */ \ /* PWM_SCALE - 1, so CCR = 255 is full off. */ \ diff --git a/pinio.h b/pinio.h index 45167d0..6d41255 100644 --- a/pinio.h +++ b/pinio.h @@ -143,13 +143,19 @@ /// Enable pullup resistor. #define _PULLUP_ON(IO) \ do { \ - IO ## _PORT->PUPDR &= ~(3 << ((IO ## _PIN) << 1)); \ - IO ## _PORT->PUPDR |= (1 << ((IO ## _PIN) << 1)); \ + IO ## _PORT->PUPDR &= ~(0x3 << ((IO ## _PIN) * 2)); \ + IO ## _PORT->PUPDR |= (0x1 << ((IO ## _PIN) * 2)); \ + } while (0) + /// Enable pulldown resistor. + #define _PULLDOWN_ON(IO) \ + do { \ + IO ## _PORT->PUPDR &= ~(0x3 << ((IO ## _PIN) * 2)); \ + IO ## _PORT->PUPDR |= (0x2 << ((IO ## _PIN) * 2)); \ } while (0) /// Disable pullup resistor. #define _PULL_OFF(IO) \ do { \ - IO ## _PORT->PUPDR &= ~(3 << ((IO ## _PIN) << 1)); \ + IO ## _PORT->PUPDR &= ~(0x3 << ((IO ## _PIN) * 2)); \ } while (0) /// Set alternate function register diff --git a/serial-stm32.c b/serial-stm32.c index 76c9a7c..5422894 100644 --- a/serial-stm32.c +++ b/serial-stm32.c @@ -13,6 +13,7 @@ #if defined TEACUP_C_INCLUDE && defined __ARM_STM32F411__ #include "arduino.h" +#include "pinio.h" #include "delay.h" #ifdef XONXOFF @@ -22,59 +23,37 @@ void serial_init() { + uint32_t tempreg; // Enable USART2 clock RCC->APB1ENR |= RCC_APB1ENR_USART2EN; // Configure the UART pins // AF 4bits per channel // Alternate functions from DM00115249.pdf datasheet (page 47; table 9) - TXD_PORT->AFR[0] |= (((uint8_t)0x07) << ((TXD_PIN) << 2)); - RXD_PORT->AFR[0] |= (((uint8_t)0x07) << ((RXD_PIN) << 2)); + SET_AFR(TXD, 0x7); + SET_AFR(RXD, 0x7); - // MODER 2bits per channel - TXD_PORT->MODER |= (2 << ((TXD_PIN) << 1)); // set bit2: alternate function - RXD_PORT->MODER |= (2 << ((RXD_PIN) << 1)); + // Set pins to alternate function mode + SET_MODE(TXD, 0x2); + SET_MODE(RXD, 0x2); - TXD_PORT->OSPEEDR |= (3 << ((TXD_PIN) << 1)); - RXD_PORT->OSPEEDR |= (3 << ((RXD_PIN) << 1)); + SET_OSPEED(TXD, 0x3); + SET_OSPEED(RXD, 0x3); - TXD_PORT->PUPDR |= (1 << ((TXD_PIN) << 1)); //Pullup - RXD_PORT->PUPDR |= (1 << ((RXD_PIN) << 1)); //Pullup? LPC has No Pull-up or Pull-down activation + PULL_OFF(TXD); + PULL_OFF(RXD); /* Disable the peripheral */ USART2->CR1 &= ~USART_CR1_UE; - /* Set the UART Communication parameters */ - /*-------------------------- USART CR2 Configuration -----------------------*/ - /* Clear STOP[13:12] bits */ - USART2->CR2 &= ~(USART_CR2_STOP); - - /* Configure the UART Stop Bits: Set STOP[13:12] bits according to huart->Init.StopBits value */ - USART2->CR2 |= 0x0000; - - /*-------------------------- USART CR1 Configuration -----------------------*/ /* Clear M, PCE, PS, TE and RE bits */ - USART2->CR1 &= ~(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ + tempreg = USART2->CR1; + tempreg &= ~(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ USART_CR1_RE | USART_CR1_OVER8); - /* Configure the UART Word Length, Parity and mode: - Set the M bits according to huart->Init.WordLength value - Set PCE and PS bits according to huart->Init.Parity value - Set TE and RE bits according to huart->Init.Mode value - Set OVER8 bit according to huart->Init.OverSampling value */ - // UART_WORDLENGTH_8B = 0x0000 - // UART_PARITY_NONE = 0x0000 - // UART_MODE_TX_RX = 0x000C - // UART_OVERSAMPLING_16 = 0x0000 - USART2->CR1 |= USART_CR1_RE | USART_CR1_TE; - - /*-------------------------- USART CR3 Configuration -----------------------*/ - /* Clear CTSE and RTSE bits */ - USART2->CR3 &= ~(USART_CR3_RTSE | USART_CR3_CTSE); - - /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */ - // UART_HWCONTROL_NONE = 0x0000 - USART2->CR3 |= 0x0000; + /* Configure the UART Word Length, Parity and mode:*/ + tempreg |= USART_CR1_RE | USART_CR1_TE; + USART2->CR1 = tempreg; /* 19.3.4 Fractional baud rate generation => reference manual for STM32F411 Set BRR for 115,200 Hz @@ -95,12 +74,23 @@ void serial_init() #define BAUD_L (((((FRACT_DIVIDER * 16) + 50) / 100)) & 0X0F) USART2->BRR = BAUD_H | BAUD_L; + + /* Clear STOP[13:12] bits */ + tempreg = USART2->CR2; + tempreg &= ~(USART_CR2_STOP); /* In asynchronous mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ - USART2->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); - USART2->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); + tempreg &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); + USART2->CR2 = tempreg; + + tempreg = USART2->CR3; + tempreg &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); + + /* Clear CTSE and RTSE bits */ + tempreg &= ~(USART_CR3_RTSE | USART_CR3_CTSE); + USART2->CR3 = tempreg; /* Enable the peripheral */ USART2->CR1 |= USART_CR1_UE;