summaryrefslogtreecommitdiff
path: root/project_starter_files/Core/Src/UART.c
diff options
context:
space:
mode:
authorgithub-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>2025-08-26 17:03:24 +0000
committerGitHub <noreply@github.com>2025-08-26 17:03:24 +0000
commit0f2ea7deaf0cba2f0ca07f6611c5a9e87d531f5b (patch)
tree66b32e47da7602942f1bf4b7d343367ac408cd5a /project_starter_files/Core/Src/UART.c
download340-repo-Sowgro-0f2ea7deaf0cba2f0ca07f6611c5a9e87d531f5b.tar.gz
340-repo-Sowgro-0f2ea7deaf0cba2f0ca07f6611c5a9e87d531f5b.tar.bz2
340-repo-Sowgro-0f2ea7deaf0cba2f0ca07f6611c5a9e87d531f5b.zip
Initial commit
Diffstat (limited to 'project_starter_files/Core/Src/UART.c')
-rw-r--r--project_starter_files/Core/Src/UART.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/project_starter_files/Core/Src/UART.c b/project_starter_files/Core/Src/UART.c
new file mode 100644
index 0000000..b1eb30c
--- /dev/null
+++ b/project_starter_files/Core/Src/UART.c
@@ -0,0 +1,152 @@
+#include "UART.h"
+
+
+// UART Ports:
+// ===================================================
+// PA.2 = USART2_TX (AF7)
+// PA.3 = USART2_RX (AF7)
+
+#define TX_PIN 2
+#define RX_PIN 3
+
+void UART2_Init(void) {
+ // Enable the clock of USART 1 & 2
+ RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN; // Enable USART 2 clock
+
+ // Select the USART1 clock source
+ // 00: PCLK selected as USART2 clock
+ // 01: System clock (SYSCLK) selected as USART2 clock
+ // 10: HSI16 clock selected as USART2 clock
+ // 11: LSE clock selected as USART2 clock
+ RCC->CCIPR &= ~RCC_CCIPR_USART2SEL;
+ RCC->CCIPR |= RCC_CCIPR_USART2SEL_0;
+
+ UART2_GPIO_Init();
+ USART_Init(USART2);
+
+ //NVIC_SetPriority(USART2_IRQn, 0); // Set Priority to 1
+ //NVIC_EnableIRQ(USART2_IRQn); // Enable interrupt of USART1 peripheral
+}
+
+void UART2_GPIO_Init(void) {
+
+ // Enable the peripheral clock of GPIO Port
+ RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
+
+ // ********************** USART 2 ***************************
+ // PA2 = USART2_TX (AF7)
+ // PA3 = USART2_RX (AF7)
+ // Alternate function, High Speed, Push pull, Pull up
+ // **********************************************************
+ // Input(00), Output(01), AlterFunc(10), Analog(11)
+ GPIOA->MODER &= ~(3<<(2*TX_PIN) | 3<<(2*RX_PIN)); // Clear bits
+ GPIOA->MODER |= 2<<(2*TX_PIN) | 2<<(2*RX_PIN);
+ GPIOA->AFR[0] &= ~(0xF<<(4*TX_PIN) | 0xF<<(4*RX_PIN));
+ GPIOA->AFR[0] |= 7<<(4*TX_PIN) | 7<<(4*RX_PIN);
+ // GPIO Speed: Low speed (00), Medium speed (01), Fast speed (10), High speed (11)
+ GPIOA->OSPEEDR |= 3<<(2*TX_PIN) | 3<<(2*RX_PIN);
+ // GPIO Push-Pull: No pull-up, pull-down (00), Pull-up (01), Pull-down (10), Reserved (11)
+ GPIOA->PUPDR &= ~(3<<(2*TX_PIN) | 3<<(2*RX_PIN));
+ // GPIO Output Type: Output push-pull (0, reset), Output open drain (1)
+ GPIOA->OTYPER &= ~(1<<TX_PIN | 1<<RX_PIN);
+}
+
+
+void USART_Init (USART_TypeDef * USARTx) {
+ // Default setting:
+ // No hardware flow control, 8 data bits, no parity, 1 start bit and 1 stop bit
+ USARTx->CR1 &= ~USART_CR1_UE; // Disable USART
+
+ // Configure word length to 8 bit
+ USARTx->CR1 &= ~USART_CR1_M; // M: 00 = 8 data bits, 01 = 9 data bits, 10 = 7 data bits
+
+ // Configure oversampling mode: Oversampling by 16
+ USARTx->CR1 &= ~USART_CR1_OVER8; // 0 = oversampling by 16, 1 = oversampling by 8
+
+ // Configure stop bits to 1 stop bit
+ // 00: 1 Stop bit; 01: 0.5 Stop bit
+ // 10: 2 Stop bits; 11: 1.5 Stop bit
+ USARTx->CR2 &= ~USART_CR2_STOP;
+
+ // CSet Baudrate to 9600 using APB frequency (80,000,000 Hz)
+ // If oversampling by 16, Tx/Rx baud = f_CK / USARTDIV,
+ // If oversampling by 8, Tx/Rx baud = 2*f_CK / USARTDIV
+ // When OVER8 = 0, BRR = USARTDIV
+ // USARTDIV = 80MHz/9600 = 8333 = 0x208D
+ USARTx->BRR = 0x208D; // Limited to 16 bits
+
+ USARTx->CR1 |= (USART_CR1_RE | USART_CR1_TE); // Transmitter and Receiver enable
+
+ if (USARTx == UART4){
+ USARTx->CR1 |= USART_CR1_RXNEIE; // Received Data Ready to be Read Interrupt
+ USARTx->CR1 &= ~USART_CR1_TCIE; // Transmission Complete Interrupt
+ USARTx->CR1 &= ~USART_CR1_IDLEIE; // Idle Line Detected Interrupt
+ USARTx->CR1 &= ~USART_CR1_TXEIE; // Transmit Data Register Empty Interrupt
+ USARTx->CR1 &= ~USART_CR1_PEIE; // Parity Error Interrupt
+ USARTx->CR1 &= ~USART_CR2_LBDIE; // LIN Break Detection Interrupt Enable
+ USARTx->CR1 &= ~USART_CR3_EIE; // Error Interrupt Enable (Frame error, noise error, overrun error)
+ //USARTx->CR3 &= ~USART_CR3_CTSIE; // CTS Interrupt
+ }
+
+ if (USARTx == USART2){
+ USARTx->ICR |= USART_ICR_TCCF;
+ USART1->CR3 |= USART_CR3_DMAT | USART_CR3_DMAR;
+ }
+
+ USARTx->CR1 |= USART_CR1_UE; // USART enable
+
+ while ( (USARTx->ISR & USART_ISR_TEACK) == 0); // Verify that the USART is ready for reception
+ while ( (USARTx->ISR & USART_ISR_REACK) == 0); // Verify that the USART is ready for transmission
+}
+
+
+uint8_t USART_Read (USART_TypeDef * USARTx) {
+ // SR_RXNE (Read data register not empty) bit is set by hardware
+ while (!(USARTx->ISR & USART_ISR_RXNE)); // Wait until RXNE (RX not empty) bit is set
+ // USART resets the RXNE flag automatically after reading DR
+ return ((uint8_t)(USARTx->RDR & 0xFF));
+ // Reading USART_DR automatically clears the RXNE flag
+}
+
+void USART_Write(USART_TypeDef * USARTx, uint8_t *buffer, uint32_t nBytes) {
+ int i;
+ // TXE is cleared by a write to the USART_DR register.
+ // TXE is set by hardware when the content of the TDR
+ // register has been transferred into the shift register.
+ for (i = 0; i < nBytes; i++) {
+ while (!(USARTx->ISR & USART_ISR_TXE)); // wait until TXE (TX empty) bit is set
+ // Writing USART_DR automatically clears the TXE flag
+ USARTx->TDR = buffer[i] & 0xFF;
+ USART_Delay(300);
+ }
+ while (!(USARTx->ISR & USART_ISR_TC)); // wait until TC bit is set
+ USARTx->ISR &= ~USART_ISR_TC;
+}
+
+
+void USART_Delay(uint32_t us) {
+ uint32_t time = 100*us/7;
+ while(--time);
+}
+
+void USART_IRQHandler(USART_TypeDef * USARTx, uint8_t *buffer, uint32_t * pRx_counter){
+ if(USARTx->ISR & USART_ISR_RXNE) { // Received data
+ buffer[*pRx_counter] = USARTx->RDR; // Reading USART_DR automatically clears the RXNE flag
+ (*pRx_counter)++;
+ if((*pRx_counter) >= BUFFER_SIZE ) {
+ (*pRx_counter) = 0;
+ }
+ } else if(USARTx->ISR & USART_ISR_TXE) {
+ //USARTx->ISR &= ~USART_ISR_TXE; // clear interrupt
+ //Tx1_Counter++;
+ } else if(USARTx->ISR & USART_ISR_ORE) { // Overrun Error
+ while(1);
+ } else if(USARTx->ISR & USART_ISR_PE) { // Parity Error
+ while(1);
+ } else if(USARTx->ISR & USART_ISR_PE) { // USART_ISR_FE
+ while(1);
+ } else if (USARTx->ISR & USART_ISR_NE){ // Noise Error Flag
+ while(1);
+ }
+}
+