From 50e0d505bab3bb1d2061c72d1948fdd2da2423ef Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 17 Apr 2016 15:36:31 +0200 Subject: Add usart_test with ds18b20 test --- src/ds18b20/ds18b20.c | 2 +- src/ds18b20/tm_stm32f4_onewire.c | 32 +++--- src/ds18b20/tm_stm32f4_onewire.h | 4 +- src/usart_test/Makefile | 124 ++++++++++++++++++++++ src/usart_test/bsp | 1 + src/usart_test/main.c | 204 ++++++++++++++++++++++++++++++++++++ src/usart_test/tm_stm32f4_ds18b20.c | 1 + src/usart_test/tm_stm32f4_ds18b20.h | 1 + src/usart_test/tm_stm32f4_onewire.c | 1 + src/usart_test/tm_stm32f4_onewire.h | 1 + 10 files changed, 354 insertions(+), 17 deletions(-) create mode 100644 src/usart_test/Makefile create mode 120000 src/usart_test/bsp create mode 100644 src/usart_test/main.c create mode 120000 src/usart_test/tm_stm32f4_ds18b20.c create mode 120000 src/usart_test/tm_stm32f4_ds18b20.h create mode 120000 src/usart_test/tm_stm32f4_onewire.c create mode 120000 src/usart_test/tm_stm32f4_onewire.h (limited to 'src') diff --git a/src/ds18b20/ds18b20.c b/src/ds18b20/ds18b20.c index 9d4ff40..7470f9d 100644 --- a/src/ds18b20/ds18b20.c +++ b/src/ds18b20/ds18b20.c @@ -41,7 +41,7 @@ void ds18b20_init() GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(GPIOB, &GPIO_InitStructure); + GPIO_Init(GPIOA, &GPIO_InitStructure); TM_OneWire_Init(&tm_onewire, GPIOA, ONEWIRE_PIN); } diff --git a/src/ds18b20/tm_stm32f4_onewire.c b/src/ds18b20/tm_stm32f4_onewire.c index f552fa1..0890b27 100644 --- a/src/ds18b20/tm_stm32f4_onewire.c +++ b/src/ds18b20/tm_stm32f4_onewire.c @@ -18,19 +18,26 @@ */ #include "tm_stm32f4_onewire.h" +void usart_debug_puts(const char* str); +void delay(const uint64_t us); + +static void +TM_GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + GPIO_SetBits(GPIOx, GPIO_Pin); +} + +static void +TM_GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + GPIO_ResetBits(GPIOx, GPIO_Pin); +} + + static void TM_GPIO_SetPinAsInput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { GPIO_SetBits(GPIOx, GPIO_Pin); -#if 0 - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_Pin = GPIO_Pin; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_Init(GPIOx, &GPIO_InitStructure); -#endif } static void @@ -45,6 +52,7 @@ TM_GPIO_SetPinAsOutput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_Init(GPIOx, &GPIO_InitStructure); #endif + GPIO_ResetBits(GPIOx, GPIO_Pin); } static int @@ -56,11 +64,7 @@ TM_GPIO_GetInputPinValue(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) static void ONEWIRE_DELAY(int us) { - const uint32_t wait_ticks = - (uint64_t)us * (uint64_t)SystemCoreClock / (uint64_t)1000000; - - const uint32_t timeout = SysTick->VAL + wait_ticks; - while (SysTick->VAL < timeout); + delay(us); } void TM_OneWire_Init(TM_OneWire_t* OneWireStruct, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { diff --git a/src/ds18b20/tm_stm32f4_onewire.h b/src/ds18b20/tm_stm32f4_onewire.h index 1301c1a..9b14109 100644 --- a/src/ds18b20/tm_stm32f4_onewire.h +++ b/src/ds18b20/tm_stm32f4_onewire.h @@ -92,8 +92,8 @@ extern C { /* Pin settings */ -#define ONEWIRE_LOW(structure) GPIO_ResetBits((structure)->GPIOx, (structure)->GPIO_Pin) -#define ONEWIRE_HIGH(structure) GPIO_SetBits((structure)->GPIOx, (structure)->GPIO_Pin) +#define ONEWIRE_LOW(structure) TM_GPIO_ResetBits((structure)->GPIOx, (structure)->GPIO_Pin) +#define ONEWIRE_HIGH(structure) TM_GPIO_SetBits((structure)->GPIOx, (structure)->GPIO_Pin) #define ONEWIRE_INPUT(structure) TM_GPIO_SetPinAsInput(structure->GPIOx, (structure)->GPIO_Pin) #define ONEWIRE_OUTPUT(structure) TM_GPIO_SetPinAsOutput(structure->GPIOx, (structure)->GPIO_Pin) diff --git a/src/usart_test/Makefile b/src/usart_test/Makefile new file mode 100644 index 0000000..e7c6fb5 --- /dev/null +++ b/src/usart_test/Makefile @@ -0,0 +1,124 @@ +### +# GNU ARM Embedded Toolchain +CC=arm-none-eabi-gcc +LD=arm-none-eabi-ld +AR=arm-none-eabi-ar +AS=arm-none-eabi-as +CP=arm-none-eabi-objcopy +OD=arm-none-eabi-objdump +SIZE=arm-none-eabi-size + +### +# Directory Structure +BINDIR=bin +SRCDIR=. + +### +# Find source files +ASOURCES=$(shell find -L $(SRCDIR) -name '*.s') +CSOURCES+=$(shell find -L $(SRCDIR) -name '*.c') +# Find header directories +INC=$(shell find -L . -name '*.h' -exec dirname {} \; | uniq) +INCLUDES=$(INC:%=-I%) +# Create object list +OBJECTS=$(ASOURCES:%.s=%.o) +OBJECTS+=$(CSOURCES:%.c=%.o) +# Define output files ELF & IHEX +BINELF=outp.elf +BINHEX=outp.hex + +### +# MCU FLAGS +MCFLAGS=-mcpu=cortex-m4 -mthumb -mlittle-endian \ +-mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb-interwork +# COMPILE FLAGS +DEFS=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DARM_MATH_CM4 -D__FPU_PRESENT=1 +CFLAGS =-Wall -ggdb -std=c99 -c $(MCFLAGS) $(DEFS) $(INCLUDES) +# LINKER FLAGS +LDSCRIPT= bsp/stm32_flash.ld +LDFLAGS =-T $(LDSCRIPT) --specs=nosys.specs $(MCFLAGS) -Wl,-Map=$(BINDIR)/outp.map + +### +# Optimizations +OPT?='O2 O3 O6' +# O1 and O4 are irrelevant +# O5 breaks FreeRTOS somehow +# I'm not trusting O7 + +ifneq ($(filter O1,$(OPT)),) +CXXFLAGS+=-fno-exceptions # Uncomment to disable exception handling +DEFS+=-DNO_EXCEPTIONS # The source code has to comply with this rule +endif + +ifneq ($(filter O2,$(OPT)),) +CFLAGS+=-Os # Optimize for size https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html +CXXFLAGS+=-Os +LDFLAGS+=-Os # Optimize for size https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html +endif + +ifneq ($(filter O3,$(OPT)),) +CFLAGS+=-ffunction-sections -fdata-sections # Place each function or data item into its own section in the output file +CXXFLAGS+=-ffunction-sections -fdata-sections # -||- +LDFLAGS+=-Wl,-gc-sections # Remove isolated unused sections +endif + +ifneq ($(filter O4,$(OPT)),) +CFLAGS+=-fno-builtin # Disable C++ exception handling +CXXFLAGS+=-fno-builtin # Disable C++ exception handling +endif + +ifneq ($(filter O5,$(OPT)),) +CFLAGS+=-flto # Enable link time optimization +CXXFLAGS+=-flto # Enable link time optimization +LDFLAGS+=-flto # Enable link time optimization +endif + +ifneq ($(filter O6,$(OPT)),) +CXXFLAGS+=-fno-rtti # Disable type introspection +endif + +ifneq ($(findstring O7,$(OPT)),) +LDFLAGS+=--specs=nano.specs # Use size optimized newlib +endif + +### +# Build Rules +.PHONY: all release debug clean + +all: release + +release: $(BINDIR)/$(BINHEX) + +debug: CFLAGS+=-g +debug: LDFLAGS+=-g +debug: release + +$(BINDIR)/$(BINHEX): $(BINDIR)/$(BINELF) + $(CP) -O ihex $< $@ + +$(BINDIR)/$(BINELF): $(OBJECTS) vc.h + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + $(SIZE) $(BINDIR)/$(BINELF) + +%.o: %.c + $(CC) $(CFLAGS) $< -o $@ + +%.o: %.s + $(CC) $(CFLAGS) $< -o $@ + +vc.h: ../../.git/logs/HEAD + echo "// This file is generated by Makefile." > vc.h + echo "// Do not edit this file!" >> vc.h + git log -1 --format="format:#define GIT_VERSION \"%h\"" >> vc.h + +clean: + rm -f $(OBJECTS) $(BINDIR)/$(BINELF) $(BINDIR)/$(BINHEX) + +# Connect to openocd's gdb server on port 3333 +deploy: $(BINDIR)/$(BINELF) +ifeq ($(wildcard /opt/openocd/bin/openocd),) + /usr/bin/openocd -f /usr/share/openocd/scripts/board/stm32f4discovery.cfg -c "program bin/"$(BINELF)" verify reset" -c "init" -c "reset" -c "exit" +else + /opt/openocd/bin/openocd -f /opt/openocd/share/openocd/scripts/board/stm32f4discovery.cfg -c "program bin/"$(BINELF)" verify reset" -c "init" -c "reset" -c "exit" +endif + diff --git a/src/usart_test/bsp b/src/usart_test/bsp new file mode 120000 index 0000000..5d9120a --- /dev/null +++ b/src/usart_test/bsp @@ -0,0 +1 @@ +../bsp \ No newline at end of file diff --git a/src/usart_test/main.c b/src/usart_test/main.c new file mode 100644 index 0000000..397d97f --- /dev/null +++ b/src/usart_test/main.c @@ -0,0 +1,204 @@ +#include "stm32f4xx.h" +#include +#include +#include +#include +#include +#include +#include "tm_stm32f4_ds18b20.h" +#include "tm_stm32f4_onewire.h" + +const uint16_t GPIOA_PIN_USART2_RX = GPIO_Pin_3; +const uint16_t GPIOA_PIN_USART2_TX = GPIO_Pin_2; + +#define ONEWIRE_PIN GPIO_Pin_1 // PA1 + +volatile uint64_t timer; +void SysTick_Handler(void) +{ + if (timer) timer--; +} + +void delay(const uint64_t us) +{ + timer = us / 10; + while (timer); +} + + + +char msg[32]; +static int cnt = 0; +void printcnt(void) +{ + snprintf(msg, 31, "%d ", cnt++); + + char* c = msg; + while (*c) { + USART_SendData(USART2, *c); + while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) ; + c++; + } +} + +static void usart_puts(USART_TypeDef* USART, const char* str) +{ + while(*str) { + // wait until data register is empty + USART_SendData(USART, *str); + while(USART_GetFlagStatus(USART, USART_FLAG_TXE) == RESET) ; + str++; + } +} +#define MAX_MSG_LEN 80 +static char usart_debug_message[MAX_MSG_LEN]; + +void usart_debug(const char *format, ...) +{ + va_list list; + va_start(list, format); + vsnprintf(usart_debug_message, MAX_MSG_LEN-1, format, list); + usart_puts(USART2, usart_debug_message); + va_end(list); +} + +void usart_debug_puts(const char* str) +{ + usart_puts(USART2, str); +} + + +static TM_OneWire_t tm_onewire; + +void ds18b20_init() +{ + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = ONEWIRE_PIN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + TM_OneWire_Init(&tm_onewire, GPIOA, ONEWIRE_PIN); +} + +int ds18b20_gettemp_one(float *temperature) +{ + uint8_t rom_addr[8]; + + TM_DS18B20_StartAll(&tm_onewire); + int status = TM_OneWire_First(&tm_onewire); + if (status) { + //Save ROM number from device + TM_OneWire_GetFullROM(&tm_onewire, rom_addr); + TM_DS18B20_Start(&tm_onewire, rom_addr); + + // The sensor needs time to do the conversion + delay(100ul * 1000ul); + status = TM_DS18B20_Read(&tm_onewire, rom_addr, temperature); + } + + return status; +} + +int ds18b20_gettemp(float *temperature) +{ + int status; + for (int i = 0; i < 10; i++) { + status = ds18b20_gettemp_one(temperature); + + if (status) { + break; + } + delay(5000ul); + } + return status; +} + + +int main(void) +{ + SysTick_Config(SystemCoreClock / 100000); // 10us tick + + // ============== PC DEBUG USART =========== + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIOA_PIN_USART2_RX | GPIOA_PIN_USART2_TX; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); + + // Setup USART2 for 9600,8,N,1 + USART_InitTypeDef USART_InitStruct; + USART_InitStruct.USART_BaudRate = 9600; + USART_InitStruct.USART_WordLength = USART_WordLength_8b; + USART_InitStruct.USART_StopBits = USART_StopBits_1; + USART_InitStruct.USART_Parity = USART_Parity_No; + USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + USART_Init(USART2, &USART_InitStruct); + +#if 0 + // enable the USART2 receive interrupt + USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); + + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_SetPriority(USART2_IRQn, 6); +#endif + + // finally this enables the complete USART2 peripheral + USART_Cmd(USART2, ENABLE); + + usart_debug_puts("DS18B20 init\r\n"); + ds18b20_init(); + + while(1) { + float temp = 0.0f; + if (ds18b20_gettemp(&temp)) { + usart_debug("Temperature %f\r\n", temp); + } + else { + usart_debug_puts("No temp\r\n"); + } + + delay(5 * 1000000ul); + } +} + +void USART2_IRQHandler(void) +{ + /* RXNE handler */ + if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) + { + /* If received 't', toggle LED and transmit 'T' */ + if((char)USART_ReceiveData(USART2) == 't') + { + USART_SendData(USART2, 'T'); + + //while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) ; + } + else { + USART_SendData(USART2, 'N'); + USART_SendData(USART2, 'o'); + USART_SendData(USART2, '!'); + USART_SendData(USART2, '\n'); + } + } +} + diff --git a/src/usart_test/tm_stm32f4_ds18b20.c b/src/usart_test/tm_stm32f4_ds18b20.c new file mode 120000 index 0000000..1dca5f5 --- /dev/null +++ b/src/usart_test/tm_stm32f4_ds18b20.c @@ -0,0 +1 @@ +../ds18b20/tm_stm32f4_ds18b20.c \ No newline at end of file diff --git a/src/usart_test/tm_stm32f4_ds18b20.h b/src/usart_test/tm_stm32f4_ds18b20.h new file mode 120000 index 0000000..6b8bae8 --- /dev/null +++ b/src/usart_test/tm_stm32f4_ds18b20.h @@ -0,0 +1 @@ +../ds18b20/tm_stm32f4_ds18b20.h \ No newline at end of file diff --git a/src/usart_test/tm_stm32f4_onewire.c b/src/usart_test/tm_stm32f4_onewire.c new file mode 120000 index 0000000..21e6c82 --- /dev/null +++ b/src/usart_test/tm_stm32f4_onewire.c @@ -0,0 +1 @@ +../ds18b20/tm_stm32f4_onewire.c \ No newline at end of file diff --git a/src/usart_test/tm_stm32f4_onewire.h b/src/usart_test/tm_stm32f4_onewire.h new file mode 120000 index 0000000..1779648 --- /dev/null +++ b/src/usart_test/tm_stm32f4_onewire.h @@ -0,0 +1 @@ +../ds18b20/tm_stm32f4_onewire.h \ No newline at end of file -- cgit v1.2.3