Update Firmware with features:
* Shellmatta implemented using UART * Version string implemented * Increased heap size * Add shellmatta printf support
This commit is contained in:
		@@ -3,7 +3,7 @@
 | 
			
		||||
#Compiler:	arm-none-eabi
 | 
			
		||||
#####################################################################################
 | 
			
		||||
#Add Files and Folders below#########################################################
 | 
			
		||||
CFILES 	= main.c syscalls.c uart/uart.c cmsis_boot/system_stm32f4xx.c systick.c
 | 
			
		||||
CFILES 	= main.c syscalls.c cmsis_boot/system_stm32f4xx.c systick.c
 | 
			
		||||
ASFILES = boot/startup_stm32f4xx.S
 | 
			
		||||
INCLUDEPATH = -Icmsis -Iinclude
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +15,9 @@ LIBRARIES = # -larm_cortexM4lf_math
 | 
			
		||||
DEFINES = -DSTM32F407xx -DSTM32F4XX -DARM_MATH_CM4 -DHSE_VALUE=8000000UL
 | 
			
		||||
mapfile = memory-mapping
 | 
			
		||||
 | 
			
		||||
GIT_VER := $(shell git describe --always --dirty --tags)
 | 
			
		||||
DEFINES += -DGIT_VER=$(GIT_VER)
 | 
			
		||||
 | 
			
		||||
ifneq ($(VERBOSE),true)
 | 
			
		||||
QUIET=@
 | 
			
		||||
else
 | 
			
		||||
@@ -25,13 +28,14 @@ endif
 | 
			
		||||
CFILES += adc-meas.c
 | 
			
		||||
 | 
			
		||||
# Shellmatta
 | 
			
		||||
CFILES += shellmatta/src/shellmatta.c shellmatta/src/shellmatta_autocomplete.c shellmatta/src/shellmatta_escape.c shellmatta/src/shellmatta_history.c shellmatta/src/shellmatta_utils.c
 | 
			
		||||
CFILES += shellmatta/src/shellmatta.c shellmatta/src/shellmatta_autocomplete.c shellmatta/src/shellmatta_escape.c shellmatta/src/shellmatta_history.c shellmatta/src/shellmatta_utils.c shell.c
 | 
			
		||||
INCLUDEPATH += -Ishellmatta/api
 | 
			
		||||
DEFINES += -DSHELLMATTA_STRIP_PRINTF
 | 
			
		||||
# DEFINES += -DSHELLMATTA_STRIP_PRINTF
 | 
			
		||||
 | 
			
		||||
# RCC Manager
 | 
			
		||||
CFILES += clock-enable-manager.c
 | 
			
		||||
 | 
			
		||||
CFILES += uart/uart.c uart/dma-ring-buffer.c
 | 
			
		||||
#TODO
 | 
			
		||||
 | 
			
		||||
###################################################################################
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								stm-firmware/include/shell.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								stm-firmware/include/shell.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
#ifndef __SHELL_H__
 | 
			
		||||
#define __SHELL_H__
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <shellmatta.h>
 | 
			
		||||
 | 
			
		||||
shellmatta_handle_t shell_init(void);
 | 
			
		||||
 | 
			
		||||
void shell_handle_input(shellmatta_handle_t shell, const char *data, size_t len);
 | 
			
		||||
 | 
			
		||||
void shell_print_string(shellmatta_handle_t shell, const char *string);
 | 
			
		||||
 | 
			
		||||
#endif /* __SHELL_H__ */
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
#ifndef __STM32GPIOMACROS_H__
 | 
			
		||||
#define __STM32GPIOMACROS_H__
 | 
			
		||||
 | 
			
		||||
#define MODER_DELETE(pin) ~(0x3U << (pin * 2))
 | 
			
		||||
#define OUTPUT(pin)  (0x01U << (pin * 2))
 | 
			
		||||
#define PULLUP(pin) (0x1U << (pin* 2))
 | 
			
		||||
#define ALTFUNC(pin) ((0x2) << (pin * 2))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,24 @@
 | 
			
		||||
#ifndef __DMA_RING_BUFFER_H__
 | 
			
		||||
#define __DMA_RING_BUFFER_H__
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stm32f4xx.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
struct dma_ring_buffer {
 | 
			
		||||
	char *data_ptr;
 | 
			
		||||
	size_t buffer_count;
 | 
			
		||||
	DMA_Stream_TypeDef *dma;
 | 
			
		||||
	size_t get_idx;
 | 
			
		||||
	uint8_t base_dma_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int dma_ring_buffer_initialize(struct dma_ring_buffer *dma_buffer, uint8_t base_dma_id, DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count, char *data_buffer, void *src_reg, uint8_t dma_trigger_channel);
 | 
			
		||||
int dma_ring_buffer_get_data(struct dma_ring_buffer *buff, const char **data_buff, size_t *len);
 | 
			
		||||
 | 
			
		||||
void dma_ring_buffer_stop(struct dma_ring_buffer *buff);
 | 
			
		||||
 | 
			
		||||
#endif /* __DMA_RING_BUFFER_H__ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,51 @@
 | 
			
		||||
/*
 | 
			
		||||
 * uart.h
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Dec 15, 2014
 | 
			
		||||
 *      Author: shino-chan
 | 
			
		||||
 */
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
#ifndef UART_UART_H_
 | 
			
		||||
#define UART_UART_H_
 | 
			
		||||
 | 
			
		||||
#define UART_RECEIVE_DMA_STREAM
 | 
			
		||||
 | 
			
		||||
#define UART_SEND_DMA_STREAM
 | 
			
		||||
 | 
			
		||||
#define UART_PORT_RCC_MASK RCC_AHB1ENR_GPIOAEN
 | 
			
		||||
 | 
			
		||||
#define UART_PORT GPIOA
 | 
			
		||||
 | 
			
		||||
#define UART_PERIPH USART1
 | 
			
		||||
#define UART_RCC_MASK RCC_APB2ENR_USART1EN
 | 
			
		||||
 | 
			
		||||
#define UART_RX_PIN 10
 | 
			
		||||
#define UART_TX_PIN 9
 | 
			
		||||
#define UART_RX_PIN_ALTFUNC 7
 | 
			
		||||
#define UART_TX_PIN_ALTFUNC 7
 | 
			
		||||
 | 
			
		||||
/* UART_DIV is 45.5625 => 115200 @ 84 MHz */
 | 
			
		||||
#define UART_DIV_FRACTION 9U /* Equals 9/16 = 0.5625 */
 | 
			
		||||
#define UART_DIV_MANTISSA 45U /* Equals 45 */
 | 
			
		||||
 | 
			
		||||
#define UART_BRR_REG_VALUE ((UART_DIV_MANTISSA<<4) | UART_DIV_FRACTION);
 | 
			
		||||
 | 
			
		||||
void initUART();
 | 
			
		||||
void sendChar(char c);
 | 
			
		||||
void sendString(char* s, int count);
 | 
			
		||||
#ifdef _P20N_
 | 
			
		||||
void yuri();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void uart_init_with_dma();
 | 
			
		||||
 | 
			
		||||
void uart_disable();
 | 
			
		||||
 | 
			
		||||
void uart_send_char(char c);
 | 
			
		||||
 | 
			
		||||
void uart_send_array(const char *data, uint32_t len);
 | 
			
		||||
 | 
			
		||||
void uart_send_string(char *string);
 | 
			
		||||
 | 
			
		||||
void uart_send_array_with_dma(char *data, uint32_t len);
 | 
			
		||||
 | 
			
		||||
void uart_send_string_with_dma(char *string);
 | 
			
		||||
 | 
			
		||||
int uart_receive_data_with_dma(const char **data, size_t *len);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* UART_UART_H_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,8 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <adc-meas.h>
 | 
			
		||||
#include <clock-enable-manager.h>
 | 
			
		||||
#include <uart/uart.h>
 | 
			
		||||
#include <shell.h>
 | 
			
		||||
 | 
			
		||||
static void setup_nvic_priorities()
 | 
			
		||||
{
 | 
			
		||||
@@ -27,7 +29,12 @@ static void setup_nvic_priorities()
 | 
			
		||||
static float pt1000_value;
 | 
			
		||||
static volatile int pt1000_value_status;
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
	const char *uart_input;
 | 
			
		||||
	size_t uart_input_len;
 | 
			
		||||
	shellmatta_handle_t shell_handle;
 | 
			
		||||
 | 
			
		||||
	rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_GPIOBEN));
 | 
			
		||||
 | 
			
		||||
	__DSB();
 | 
			
		||||
@@ -40,8 +47,18 @@ int main() {
 | 
			
		||||
	//setup_dma(&adc_results, 3);
 | 
			
		||||
	adc_pt1000_setup_meas();
 | 
			
		||||
 | 
			
		||||
	uart_init_with_dma();
 | 
			
		||||
 | 
			
		||||
	shell_handle = shell_init();
 | 
			
		||||
 | 
			
		||||
	while(1) {
 | 
			
		||||
		pt1000_value_status = adc_pt1000_get_current_resistance(&pt1000_value);
 | 
			
		||||
 | 
			
		||||
		if (uart_receive_data_with_dma(&uart_input, &uart_input_len) >= 0) {
 | 
			
		||||
			shell_handle_input(shell_handle, uart_input, uart_input_len);
 | 
			
		||||
		}
 | 
			
		||||
		//systick_wait_ms(300);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										139
									
								
								stm-firmware/shell.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								stm-firmware/shell.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
#include <shell.h>
 | 
			
		||||
#include <uart/uart.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <adc-meas.h>
 | 
			
		||||
 | 
			
		||||
#define xstr(x) str(x)
 | 
			
		||||
#define str(x) #x
 | 
			
		||||
 | 
			
		||||
#ifndef GIT_VER
 | 
			
		||||
#define GIT_VER "VERSION NOT SET"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static shellmatta_instance_t shell;
 | 
			
		||||
static char shell_buffer[512];
 | 
			
		||||
static char history_buffer[1024];
 | 
			
		||||
 | 
			
		||||
static shellmatta_retCode_t write_shell_callback(const char *data, uint32_t len)
 | 
			
		||||
{
 | 
			
		||||
	uart_send_array(data, len);
 | 
			
		||||
 | 
			
		||||
	return SHELLMATTA_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static shellmatta_retCode_t shell_cmd_ver(const shellmatta_handle_t   handle,
 | 
			
		||||
						    const char                  *arguments,
 | 
			
		||||
						    uint32_t                    length)
 | 
			
		||||
{
 | 
			
		||||
	(void)arguments;
 | 
			
		||||
	(void)length;
 | 
			
		||||
 | 
			
		||||
	shellmatta_printf(handle, "Reflow Oven Controller Firmware %s", xstr(GIT_VER));
 | 
			
		||||
 | 
			
		||||
	return SHELLMATTA_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static shellmatta_retCode_t shell_cmd_pt1000_res(const shellmatta_handle_t   handle,
 | 
			
		||||
						 const char                  *arguments,
 | 
			
		||||
						 uint32_t length)
 | 
			
		||||
{
 | 
			
		||||
	(void)arguments;
 | 
			
		||||
	(void)length;
 | 
			
		||||
	float resistance;
 | 
			
		||||
	int pt1000_status;
 | 
			
		||||
	const char *display_status;
 | 
			
		||||
	enum adc_pt1000_error pt1000_flags;
 | 
			
		||||
	const char *status_text[] = {"VALID", "WATCHDOG", "DATA-OVERFLOW", "UNSTABLE"};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	display_status = status_text[0];
 | 
			
		||||
	pt1000_status = adc_pt1000_get_current_resistance(&resistance);
 | 
			
		||||
 | 
			
		||||
	if (pt1000_status == 2) {
 | 
			
		||||
		display_status = status_text[3];
 | 
			
		||||
	} else if (pt1000_status) {
 | 
			
		||||
		pt1000_flags = adc_pt1000_check_error();
 | 
			
		||||
		if (pt1000_flags & ADC_PT1000_WATCHDOG_ERROR)
 | 
			
		||||
			display_status = status_text[1];
 | 
			
		||||
		else if (pt1000_flags & ADC_PT1000_OVERFLOW)
 | 
			
		||||
			display_status = status_text[2];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	shellmatta_printf(handle, "PT1000 resistance: %.2f Ohm [%s]\r\n", resistance, display_status);
 | 
			
		||||
 | 
			
		||||
	return SHELLMATTA_OK;
 | 
			
		||||
}
 | 
			
		||||
static shellmatta_retCode_t shell_cmd_clear_error_status(const shellmatta_handle_t   handle,
 | 
			
		||||
						 const char                  *arguments,
 | 
			
		||||
						 uint32_t length)
 | 
			
		||||
{
 | 
			
		||||
	adc_pt1000_clear_error();
 | 
			
		||||
 | 
			
		||||
	return SHELLMATTA_OK;
 | 
			
		||||
}
 | 
			
		||||
//typedef struct shellmatta_cmd
 | 
			
		||||
//{
 | 
			
		||||
//    char                    *cmd;       /**< command name                           */
 | 
			
		||||
//    char                    *cmdAlias;  /**< command alias                          */
 | 
			
		||||
//    char                    *helpText;  /**< help text to print in "help" command   */
 | 
			
		||||
//    char                    *usageText; /**< usage text to print on parameter error */
 | 
			
		||||
//    shellmatta_cmdFct_t     cmdFct;     /**< pointer to the cmd callack function    */
 | 
			
		||||
//    struct shellmatta_cmd   *next;      /**< pointer to next command or NULL        */
 | 
			
		||||
//} shellmatta_cmd_t;
 | 
			
		||||
 | 
			
		||||
static shellmatta_cmd_t cmd[3] = {
 | 
			
		||||
	{
 | 
			
		||||
		.cmd = "version",
 | 
			
		||||
		.cmdAlias = "ver",
 | 
			
		||||
		.helpText = "Print firmware version",
 | 
			
		||||
		.usageText = NULL,
 | 
			
		||||
		.cmdFct = shell_cmd_ver,
 | 
			
		||||
		.next = &cmd[1],
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		.cmd = "pt1000",
 | 
			
		||||
		.cmdAlias = "pt",
 | 
			
		||||
		.helpText = "Get current filtered and calibrated PT1000 resistance",
 | 
			
		||||
		.usageText = NULL,
 | 
			
		||||
		.cmdFct = shell_cmd_pt1000_res,
 | 
			
		||||
		.next = &cmd[2],
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		.cmd = "pt1000-clear-error",
 | 
			
		||||
		.cmdAlias = "pt-clear",
 | 
			
		||||
		.helpText = "Clear error status of PT1000 reading",
 | 
			
		||||
		.usageText = NULL,
 | 
			
		||||
		.cmdFct = shell_cmd_clear_error_status,
 | 
			
		||||
		.next = NULL,
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
shellmatta_handle_t shell_init(void)
 | 
			
		||||
{
 | 
			
		||||
	shellmatta_handle_t handle;
 | 
			
		||||
	shellmatta_retCode_t ret;
 | 
			
		||||
 | 
			
		||||
	ret = shellmatta_doInit(&shell, &handle, shell_buffer, sizeof(shell_buffer), history_buffer, sizeof(history_buffer),
 | 
			
		||||
			  "Enter command:\r\n", cmd, write_shell_callback);
 | 
			
		||||
	if (ret != SHELLMATTA_OK)
 | 
			
		||||
		handle = NULL;
 | 
			
		||||
 | 
			
		||||
	return handle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void shell_handle_input(shellmatta_handle_t shell, const char *data, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	 if (!shell)
 | 
			
		||||
		 return;
 | 
			
		||||
 | 
			
		||||
	 shellmatta_processData(shell, (char *)data, (uint32_t)len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void shell_print_string(shellmatta_handle_t shell, const char *string)
 | 
			
		||||
{
 | 
			
		||||
	if (!shell)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	shellmatta_write(shell, (char *)string, strlen(string));
 | 
			
		||||
}
 | 
			
		||||
@@ -36,8 +36,8 @@ ENTRY(Reset_Handler)
 | 
			
		||||
_estack = 0x20020000;    /* end of 128K RAM on AHB bus*/
 | 
			
		||||
 | 
			
		||||
/* Generate a link error if heap and stack don't fit into RAM */
 | 
			
		||||
_Min_Heap_Size = 0x1000;      /* required amount of heap (DEFAULT 0) */
 | 
			
		||||
_Min_Stack_Size = 0x1000 ; /* required amount of stack */
 | 
			
		||||
_Min_Heap_Size = 0x1500;      /* required amount of heap (DEFAULT 0) */
 | 
			
		||||
_Min_Stack_Size = 0x2000 ; /* required amount of stack */
 | 
			
		||||
/* recommended min stack size for printf=0x2000, orig = 0x400 */
 | 
			
		||||
 | 
			
		||||
/* Specify the memory areas */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,2 +1,93 @@
 | 
			
		||||
#include <uart/dma-ring-buffer.h>
 | 
			
		||||
#include <clock-enable-manager.h>
 | 
			
		||||
 | 
			
		||||
int dma_ring_buffer_initialize(struct dma_ring_buffer *dma_buffer, uint8_t base_dma_id, DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count, char *data_buffer, void* src_reg, uint8_t dma_trigger_channel)
 | 
			
		||||
{
 | 
			
		||||
	if (!dma_buffer || !dma_stream || !data_buffer || !src_reg)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	if (dma_trigger_channel > 7)
 | 
			
		||||
		return -3;
 | 
			
		||||
 | 
			
		||||
	dma_buffer->base_dma_id = base_dma_id;
 | 
			
		||||
 | 
			
		||||
	switch (base_dma_id) {
 | 
			
		||||
	case 1:
 | 
			
		||||
		rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_DMA1EN));
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_DMA2EN));
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return -2;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dma_buffer->dma = dma_stream;
 | 
			
		||||
	dma_buffer->get_idx = 0;
 | 
			
		||||
	dma_buffer->buffer_count = buffer_element_count;
 | 
			
		||||
 | 
			
		||||
	dma_buffer->data_ptr = data_buffer;
 | 
			
		||||
 | 
			
		||||
	dma_stream->PAR = (uint32_t)src_reg;
 | 
			
		||||
	dma_stream->M0AR = (uint32_t)data_buffer;
 | 
			
		||||
	dma_stream->NDTR = buffer_element_count;
 | 
			
		||||
	dma_stream->NDTR = buffer_element_count;
 | 
			
		||||
 | 
			
		||||
	dma_stream->CR |= (dma_trigger_channel<<25) | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_EN;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dma_ring_buffer_get_data(struct dma_ring_buffer *buff, const char **data_buff, size_t *len)
 | 
			
		||||
{
 | 
			
		||||
	int ret_code = 0;
 | 
			
		||||
	uint32_t ndtr;
 | 
			
		||||
	size_t put_idx;
 | 
			
		||||
 | 
			
		||||
	if (!buff || !data_buff || !len)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	ndtr = buff->dma->NDTR;
 | 
			
		||||
	put_idx = buff->buffer_count - ndtr;
 | 
			
		||||
 | 
			
		||||
	/* Check if wrap around */
 | 
			
		||||
	if (put_idx < buff->get_idx) {
 | 
			
		||||
		*data_buff = &(buff->data_ptr[buff->get_idx]);
 | 
			
		||||
		*len = buff->buffer_count - buff->get_idx;
 | 
			
		||||
		buff->get_idx = 0;
 | 
			
		||||
		ret_code = 1;
 | 
			
		||||
	} else if (put_idx > buff->get_idx) {
 | 
			
		||||
		*data_buff = &(buff->data_ptr[buff->get_idx]);
 | 
			
		||||
		*len = put_idx - buff->get_idx;
 | 
			
		||||
		buff->get_idx += *len;
 | 
			
		||||
	} else {
 | 
			
		||||
		/* No new data */
 | 
			
		||||
		*len = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dma_ring_buffer_stop(struct dma_ring_buffer *buff)
 | 
			
		||||
{
 | 
			
		||||
	if (!buff || !buff->dma)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	buff->dma->CR = 0;
 | 
			
		||||
	buff->dma->NDTR = 0;
 | 
			
		||||
	buff->dma->M1AR = 0;
 | 
			
		||||
	buff->dma->FCR = 0;
 | 
			
		||||
 | 
			
		||||
	switch (buff->base_dma_id) {
 | 
			
		||||
	case 1:
 | 
			
		||||
		rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_DMA1EN));
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_DMA2EN));
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,12 @@
 | 
			
		||||
//Alternate Function 7
 | 
			
		||||
#include <uart/uart.h>
 | 
			
		||||
#include <stm32f4xx.h>
 | 
			
		||||
#include <clock-enable-manager.h>
 | 
			
		||||
#include <stm32-gpio-macros.h>
 | 
			
		||||
#include <uart/dma-ring-buffer.h>
 | 
			
		||||
 | 
			
		||||
static struct dma_ring_buffer ring_buff;
 | 
			
		||||
static char uart_rx_buffer[64];
 | 
			
		||||
 | 
			
		||||
void initUART() {
 | 
			
		||||
	__DSB();
 | 
			
		||||
@@ -28,6 +34,7 @@ void initUART() {
 | 
			
		||||
	USART2->CR1 = USART_CR1_UE | USART_CR1_TE;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sendChar(char c) {
 | 
			
		||||
	while(!(USART2->SR & USART_SR_TXE));
 | 
			
		||||
	USART2->DR = c;
 | 
			
		||||
@@ -42,3 +49,66 @@ void sendString(char* s, int count) {
 | 
			
		||||
		sendChar(*s);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void uart_gpio_config()
 | 
			
		||||
{
 | 
			
		||||
	rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(UART_PORT_RCC_MASK));
 | 
			
		||||
	UART_PORT->MODER &=  MODER_DELETE(UART_TX_PIN) & MODER_DELETE(UART_RX_PIN);
 | 
			
		||||
	UART_PORT->MODER |= ALTFUNC(UART_RX_PIN) | ALTFUNC(UART_TX_PIN);
 | 
			
		||||
	SETAF(UART_PORT, UART_RX_PIN, UART_RX_PIN_ALTFUNC);
 | 
			
		||||
	SETAF(UART_PORT, UART_TX_PIN, UART_TX_PIN_ALTFUNC);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void uart_init_with_dma()
 | 
			
		||||
{
 | 
			
		||||
	rcc_manager_enable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(UART_RCC_MASK));
 | 
			
		||||
	uart_gpio_config();
 | 
			
		||||
 | 
			
		||||
	UART_PERIPH->BRR = UART_BRR_REG_VALUE;
 | 
			
		||||
	UART_PERIPH->CR3 = USART_CR3_DMAR | USART_CR3_DMAT;
 | 
			
		||||
	UART_PERIPH->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
 | 
			
		||||
 | 
			
		||||
	dma_ring_buffer_initialize(&ring_buff, 2, DMA2_Stream5, sizeof(uart_rx_buffer), uart_rx_buffer, (char *)&UART_PERIPH->DR, 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void uart_disable()
 | 
			
		||||
{
 | 
			
		||||
	UART_PERIPH->CR1 = 0;
 | 
			
		||||
	UART_PERIPH->CR2 = 0;
 | 
			
		||||
	UART_PERIPH->CR3 = 0;
 | 
			
		||||
	dma_ring_buffer_stop(&ring_buff);
 | 
			
		||||
 | 
			
		||||
	rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(UART_PORT_RCC_MASK));
 | 
			
		||||
	rcc_manager_disable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(UART_RCC_MASK));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void uart_send_char(char c)
 | 
			
		||||
{
 | 
			
		||||
	while(!(UART_PERIPH->SR & USART_SR_TXE));
 | 
			
		||||
	UART_PERIPH->DR = c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void uart_send_array(const char *data, uint32_t len)
 | 
			
		||||
{
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < len; i++)
 | 
			
		||||
		uart_send_char(data[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void uart_send_string(char *string)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; string[i] != '\0'; i++)
 | 
			
		||||
		uart_send_char(string[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void uart_send_array_with_dma(char *data, uint32_t len);
 | 
			
		||||
 | 
			
		||||
void uart_send_string_with_dma(char *string);
 | 
			
		||||
 | 
			
		||||
int uart_receive_data_with_dma(const char **data, size_t *len)
 | 
			
		||||
{
 | 
			
		||||
	return dma_ring_buffer_get_data(&ring_buff, data, len);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user