summaryrefslogtreecommitdiff
path: root/project/Core/Src/Devices
diff options
context:
space:
mode:
Diffstat (limited to 'project/Core/Src/Devices')
-rw-r--r--project/Core/Src/Devices/GPIO.c50
-rw-r--r--project/Core/Src/Devices/LED.c49
-rw-r--r--project/Core/Src/Devices/UART.c152
-rw-r--r--project/Core/Src/Devices/adc.c130
-rw-r--r--project/Core/Src/Devices/dac.c83
5 files changed, 464 insertions, 0 deletions
diff --git a/project/Core/Src/Devices/GPIO.c b/project/Core/Src/Devices/GPIO.c
new file mode 100644
index 0000000..f3812fa
--- /dev/null
+++ b/project/Core/Src/Devices/GPIO.c
@@ -0,0 +1,50 @@
+/*
+ * gpio.c
+ *
+ * Created on: Nov 4, 2021
+ * Author: Mitesh Parikh
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "GPIO.h"
+#include <stdbool.h>
+#include "stm32l4xx.h"
+
+// External Global Variables that we will need access to
+
+
+/*----------------------------------------------------------------------------*/
+/* Configure GPIO */
+/*----------------------------------------------------------------------------*/
+void GPIO_Init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ /* GPIO Ports Clock Enable */
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+
+ /*Configure GPIO pin : PtPin */
+ GPIO_InitStruct.Pin = B1_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = S1_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
+ GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+ HAL_GPIO_Init(S1_GPIO_Port, &GPIO_InitStruct);
+
+ /* EXTI15_10_IRQn interrupt init*/
+ // Note you will have to add EXTI15_10_IRQn Interrupt handler function as well
+ // This is the interrupt handler for the blue button
+
+
+ /* EXTI9_5_IRQn interrupt init*/
+ // Note you will have to add EXTI9_15_IRQn Interrupt handler function as well
+ // This is the interrupt handler for the external buttons (S1)
+}
+
diff --git a/project/Core/Src/Devices/LED.c b/project/Core/Src/Devices/LED.c
new file mode 100644
index 0000000..8b1b9b2
--- /dev/null
+++ b/project/Core/Src/Devices/LED.c
@@ -0,0 +1,49 @@
+#include "LED.h"
+
+
+//******************************************************************************************
+// User LED = LD2 Green LED = PA.5
+//******************************************************************************************
+#define LED_PIN 5
+
+void LED_Init(void){
+
+ // Enable the peripheral clock of GPIO Port
+ RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
+
+ // GPIO Mode: Input(00), Output(01), AlterFunc(10), Analog(11, reset)
+ GPIOA->MODER &= ~(3U<<(2*LED_PIN));
+ GPIOA->MODER |= 1U<<(2*LED_PIN); // Output(01)
+
+ // GPIO Speed: Low speed (00), Medium speed (01), Fast speed (10), High speed (11)
+ GPIOA->OSPEEDR &= ~(3U<<(2*LED_PIN));
+ GPIOA->OSPEEDR |= 3U<<(2*LED_PIN); // High speed
+
+ // GPIO Output Type: Output push-pull (0, reset), Output open drain (1)
+ GPIOA->OTYPER &= ~(1U<<LED_PIN); // Push-pull
+
+ // GPIO Push-Pull: No pull-up, pull-down (00), Pull-up (01), Pull-down (10), Reserved (11)
+ GPIOA->PUPDR &= ~(3U<<(2*LED_PIN)); // No pull-up, no pull-down
+
+}
+
+//******************************************************************************************
+// Turn LED On
+//******************************************************************************************
+void LED_On(void){
+ GPIOA->ODR |= (1UL<<LED_PIN);
+}
+
+//******************************************************************************************
+// Turn LED Off
+//******************************************************************************************
+void LED_Off(void){
+ GPIOA->ODR &= ~(1UL<<LED_PIN);
+}
+
+//******************************************************************************************
+// Toggle LED
+//******************************************************************************************
+void LED_Toggle(void){
+ GPIOA->ODR ^= (1UL<<LED_PIN);
+}
diff --git a/project/Core/Src/Devices/UART.c b/project/Core/Src/Devices/UART.c
new file mode 100644
index 0000000..b1eb30c
--- /dev/null
+++ b/project/Core/Src/Devices/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);
+ }
+}
+
diff --git a/project/Core/Src/Devices/adc.c b/project/Core/Src/Devices/adc.c
new file mode 100644
index 0000000..549f4bb
--- /dev/null
+++ b/project/Core/Src/Devices/adc.c
@@ -0,0 +1,130 @@
+/*
+ * adc.c
+ *
+ * Created on: Apr 13, 2022
+ * Author: bruce
+ */
+
+#include "adc.h"
+#include "stm32l4xx.h"
+#include "main.h"
+
+ADC_HandleTypeDef hadc1;
+
+/**
+* @brief ADC MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hadc: ADC handle pointer
+* @retval None
+*/
+void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+ if(hadc->Instance==ADC1)
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
+ PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
+ PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSI;
+ PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
+ PeriphClkInit.PLLSAI1.PLLSAI1N = 8;
+ PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
+ PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
+ PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
+ PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_ADC1CLK;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+
+ /* Peripheral clock enable */
+ __HAL_RCC_ADC_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ /**ADC1 GPIO Configuration
+ PA0 ------> ADC1_IN5
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_0;
+ GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+ }
+
+}
+
+/**
+* @brief ADC MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hadc: ADC handle pointer
+* @retval None
+*/
+void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
+{
+ if(hadc->Instance==ADC1)
+ {
+ __HAL_RCC_ADC_CLK_DISABLE();
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);
+ }
+
+}
+
+void ADC_Init () {
+ ADC_MultiModeTypeDef multimode = {0};
+ ADC_ChannelConfTypeDef sConfig = {0};
+
+ /** Common config
+ */
+ hadc1.Instance = ADC1;
+ hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
+ hadc1.Init.Resolution = ADC_RESOLUTION_12B;
+ hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
+ hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
+ hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
+ hadc1.Init.LowPowerAutoWait = DISABLE;
+ hadc1.Init.ContinuousConvMode = DISABLE;
+ hadc1.Init.NbrOfConversion = 1;
+ hadc1.Init.DiscontinuousConvMode = DISABLE;
+ hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
+ hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
+ hadc1.Init.DMAContinuousRequests = DISABLE;
+ hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
+ hadc1.Init.OversamplingMode = DISABLE;
+ if (HAL_ADC_Init(&hadc1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure the ADC multi-mode
+ */
+ multimode.Mode = ADC_MODE_INDEPENDENT;
+ if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+
+ /** Configure Regular Channel
+ */
+ sConfig.Channel = ADC_CHANNEL;
+ sConfig.Rank = ADC_REGULAR_RANK_1;
+ sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
+ sConfig.SingleDiff = ADC_SINGLE_ENDED;
+ sConfig.OffsetNumber = ADC_OFFSET_NONE;
+ sConfig.Offset = 0;
+ if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+void ADC_Start () {
+ HAL_ADC_Start (&hadc1);
+}
+
+uint32_t ADC_Read_Value_Blocking () {
+ HAL_ADC_PollForConversion (&hadc1, 10);
+ return HAL_ADC_GetValue (&hadc1);
+}
diff --git a/project/Core/Src/Devices/dac.c b/project/Core/Src/Devices/dac.c
new file mode 100644
index 0000000..e03f9ce
--- /dev/null
+++ b/project/Core/Src/Devices/dac.c
@@ -0,0 +1,83 @@
+/*
+ * dac.c
+ *
+ * Created on: Apr 13, 2022
+ * Author: bruce
+ */
+
+#include "dac.h"
+#include "main.h"
+#include "stm32l4xx.h"
+
+DAC_HandleTypeDef hdac1;
+
+/**
+* @brief DAC MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hdac: DAC handle pointer
+* @retval None
+*/
+void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hdac->Instance==DAC1)
+ {
+ __HAL_RCC_DAC1_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ GPIO_InitStruct.Pin = GPIO_PIN_4;
+ GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+ }
+
+}
+
+/**
+* @brief DAC MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hdac: DAC handle pointer
+* @retval None
+*/
+void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac)
+{
+ if(hdac->Instance==DAC1)
+ {
+ __HAL_RCC_DAC1_CLK_DISABLE();
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4);
+ }
+
+}
+
+void DAC_Init () {
+ DAC_ChannelConfTypeDef sConfig = {0};
+
+ /** DAC Initialization
+ */
+ hdac1.Instance = DAC1;
+ if (HAL_DAC_Init(&hdac1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** DAC channel OUT1 config
+ */
+ sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
+ sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
+ sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
+ sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
+ sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
+
+ if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+void DAC_Start () {
+ HAL_DAC_Start (&hdac1, DAC_CHANNEL_1);
+}
+
+void DAC_Set_Value (uint32_t value) {
+ HAL_DAC_SetValue (&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value);
+}