diff --git a/.gitignore b/.gitignore index c80c022..a21e0e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ cube/build/ -.*.sw? \ No newline at end of file +.*.sw? +*.o +test \ No newline at end of file diff --git a/cube/Makefile b/cube/Makefile index f0d93c9..3ed1be9 100644 --- a/cube/Makefile +++ b/cube/Makefile @@ -1,4 +1,4 @@ -# Processed by ../tools/insertMyCode.sh +# Processed by ../tools/insertMyCode.sh ########################################################################################################################## # File automatically-generated by tool: [projectgenerator] version: [3.10.0-B14] date: [Tue Oct 27 22:02:19 CET 2020] ########################################################################################################################## @@ -36,36 +36,36 @@ BUILD_DIR = build # source ###################################### # C sources -C_SOURCES = \ -User/Src/led.c User/Src/loopCtrl.c User/Src/main2.c hottislib/PontCoopScheduler.c \ -Core/Src/main.c \ -Core/Src/gpio.c \ -Core/Src/adc.c \ -Core/Src/spi.c \ -Core/Src/usart.c \ -Core/Src/stm32f1xx_it.c \ -Core/Src/stm32f1xx_hal_msp.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c \ -Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c \ +C_SOURCES = \ +User/Src/mbusComm.c User/Src/led.c User/Src/loopCtrl.c User/Src/main2.c hottislib/PontCoopScheduler.c \ +Core/Src/main.c \ +Core/Src/gpio.c \ +Core/Src/adc.c \ +Core/Src/spi.c \ +Core/Src/usart.c \ +Core/Src/stm32f1xx_it.c \ +Core/Src/stm32f1xx_hal_msp.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c \ +Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c \ Core/Src/system_stm32f1xx.c # ASM sources -ASM_SOURCES = \ +ASM_SOURCES = \ startup_stm32f103xe.s @@ -109,8 +109,8 @@ MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) AS_DEFS = # C defines -C_DEFS = \ --DUSE_HAL_DRIVER \ +C_DEFS = \ +-DUSE_HAL_DRIVER \ -DSTM32F103xE @@ -118,14 +118,14 @@ C_DEFS = \ AS_INCLUDES = # C includes -C_INCLUDES = \ --Ihottislib \ --IUser/Inc \ --ICore/Inc \ --IDrivers/STM32F1xx_HAL_Driver/Inc \ --IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy \ --IDrivers/CMSIS/Device/ST/STM32F1xx/Include \ --IDrivers/CMSIS/Include \ +C_INCLUDES = \ +-Ihottislib \ +-IUser/Inc \ +-ICore/Inc \ +-IDrivers/STM32F1xx_HAL_Driver/Inc \ +-IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy \ +-IDrivers/CMSIS/Device/ST/STM32F1xx/Include \ +-IDrivers/CMSIS/Include \ -IDrivers/CMSIS/Include diff --git a/cube/User/Inc/logger.h b/cube/User/Inc/logger.h new file mode 100644 index 0000000..4c3b92c --- /dev/null +++ b/cube/User/Inc/logger.h @@ -0,0 +1,6 @@ +#ifndef _LOGGER_H_ +#define _LOGGER_H_ + +void log(char *msg); + +#endif // _LOGGER_H_ diff --git a/cube/User/Inc/mbusComm.h b/cube/User/Inc/mbusComm.h new file mode 100644 index 0000000..d8999db --- /dev/null +++ b/cube/User/Inc/mbusComm.h @@ -0,0 +1,8 @@ +#ifndef _MBUSCOMM_H_ +#define _MBUSCOMM_H_ + +#include + +void mbusCommRequest(uint8_t cmd, uint8_t addr); + +#endif // _MBUSCOMM_H_ diff --git a/cube/User/Inc/ringbuffer.h b/cube/User/Inc/ringbuffer.h new file mode 100644 index 0000000..c4601e5 --- /dev/null +++ b/cube/User/Inc/ringbuffer.h @@ -0,0 +1,23 @@ +#ifndef _RINGBUFFER_H_ +#define _RINGBUFFER_H_ + +#include +#include + + +typedef struct { + uint32_t bufferReadIdx; + uint32_t bufferWriteIdx; + uint32_t bufferSize; + uint8_t* buffer; +} ringbuffer_t; + +void ringbufferInit(ringbuffer_t *handle, uint32_t bufferSize); +void ringbufferFree(ringbuffer_t *handle); +int ringbufferPut(ringbuffer_t *handle, uint8_t *data, uint32_t dataLen); +uint8_t *ringbufferGet(ringbuffer_t *handle, uint32_t dataLen); +bool ringbufferEmpty(ringbuffer_t *handle); +int ringbufferGetOne(ringbuffer_t *handle); // if positive, cast to uint8_t and be happy, if negative error + + +#endif // _RINGBUFFER_H_ diff --git a/cube/User/Src/logger.c b/cube/User/Src/logger.c new file mode 100644 index 0000000..2698e92 --- /dev/null +++ b/cube/User/Src/logger.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include +#include +#include + +void log(char *msg) { + uint16_t len = strlen(msg); + + if (HAL_UART_Transmit_IT(&debugUart, msg, len) != HAL_OK) { + if(RingBuffer_Write(&txBuf, msg, len) != RING_BUFFER_OK) + return 0; + } + return 1; +} diff --git a/cube/User/Src/main2.c b/cube/User/Src/main2.c index dbc2e1e..f881f26 100644 --- a/cube/User/Src/main2.c +++ b/cube/User/Src/main2.c @@ -9,6 +9,8 @@ #include #include +#include + void my_setup_1() { schInit(); @@ -18,53 +20,21 @@ void my_errorHandler() { ledRed(true); } - - -void blinkRed(void *handle) { - static bool on = false; - ledRed(on); - on ^= true; -} - -void blinkGreen(void *handle) { - static bool on = false; - ledGreen(on); - on ^= true; -} - void helloWorld(void *handle) { static char hello[] = "Hello World\n\r"; HAL_UART_Transmit_IT(&debugUart, (uint8_t*) hello, strlen(hello)); } void helloMeterbus(void *handle) { - static char hello[] = "Hello Meterbus\n\r"; - if (! loopActive) { - loopEnable(); - ledRed(false); - } - - HAL_UART_Transmit_IT(&mbusUart, (uint8_t*) hello, strlen(hello)); + mbusCommRequest(0x5b, 80); } -void toggleLoop(void *handle) { - static bool state = false; - - if (state) { - loopDisable(); - } else { - ledRed(false); - loopEnable(); - } - state ^= true; -} void my_setup_2() { ledRed(false); ledGreen(true); schAdd(helloWorld, NULL, 0, 5000); - // schAdd(toggleLoop, NULL, 0, 10000); schAdd(helloMeterbus, NULL, 0, 10000); } diff --git a/cube/User/Src/mbusComm.c b/cube/User/Src/mbusComm.c new file mode 100644 index 0000000..0a2da74 --- /dev/null +++ b/cube/User/Src/mbusComm.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include + + + +typedef enum { + IDLE, + SEND, + SEND_CONT +} e_mbusCommState; + +typedef struct { + e_mbusCommState state; + uint8_t retryCnt; + uint8_t cmd; + uint8_t addr; + uint8_t sendBuf[5]; +} t_mbusCommHandle; + +static t_mbusCommHandle mbusCommHandle = { .state = IDLE, .retryCnt = 0, .cmd = 0, .addr = 0 }; + + +static void handleRequestEngine(void *handle) { + t_mbusCommHandle *myHandle = (t_mbusCommHandle*) handle; + + switch (myHandle->state) { + case IDLE: + break; + + case SEND: + myHandle->sendBuf[0] = 0x10; + myHandle->sendBuf[1] = myHandle->cmd; + myHandle->sendBuf[2] = myHandle->addr; + myHandle->sendBuf[3] = myHandle->cmd + myHandle->addr; // checksum + myHandle->sendBuf[4] = 0x16; + myHandle->state = SEND_CONT; + // no break !! + + case SEND_CONT: + ledRed(false); + if (! loopActive) { + myHandle->retryCnt++; + loopEnable(); + schAdd(handleRequestEngine, handle, 10, 0); + } else { + // write(fd, sendBuf, 5); + HAL_UART_Transmit_IT(&mbusUart, myHandle->sendBuf, 5); + myHandle->state = IDLE; + } + break; + + default: + myHandle->state = IDLE; + break; + } +} + + +void mbusCommRequest(uint8_t cmd, uint8_t addr) { + if (mbusCommHandle.state == IDLE) { + mbusCommHandle.state = SEND; + mbusCommHandle.retryCnt = 0; + mbusCommHandle.cmd = cmd; + mbusCommHandle.addr = addr; + schAdd(handleRequestEngine, (void*) &mbusCommHandle, 0, 0); + } else { + // busy + } +} + diff --git a/cube/User/Src/ringbuffer.c b/cube/User/Src/ringbuffer.c new file mode 100644 index 0000000..d934800 --- /dev/null +++ b/cube/User/Src/ringbuffer.c @@ -0,0 +1,105 @@ +#include +#include +#include + + + + +/* +typedef struct { + uint32_t bufferReadIdx; + uint32_t bufferWriteIdx; + uint32_t bufferSize; + uint8_t* buffer; +} ringbuffer_t; +*/ + + +void ringbufferInit(ringbuffer_t *handle, uint32_t bufferSize) { + handle->bufferSize = bufferSize; + handle->buffer = (uint8_t*) malloc(handle->bufferSize); + memset(handle->buffer, 0, handle->bufferSize); + handle->bufferReadIdx = 0; + handle->bufferWriteIdx = 0; +} + +void ringbufferFree(ringbuffer_t *handle) { + free(handle->buffer); + handle->buffer = NULL; + handle->bufferSize = 0; + handle->bufferReadIdx = 0; + handle->bufferWriteIdx = 0; +} + +/* +void ringbufferPut(ringbuffer_t *handle, void *f) { + if (handle->bufferWriteIdx == (BUFFER_SIZE - 1)) { + while (handle->bufferReadIdx == BUFFER_SIZE); + } else { + while (handle->bufferReadIdx == (handle->bufferWriteIdx + 1)); + } + + handle->buffer[handle->bufferWriteIdx] = f; + handle->bufferWriteIdx++; + + if (handle->bufferWriteIdx > BUFFER_SIZE) { + handle->bufferWriteIdx = 0; + } + + pthread_mutex_lock(&(handle->eventMutex)); + pthread_cond_signal(&(handle->eventSignal)); + pthread_mutex_unlock(&(handle->eventMutex)); +} +*/ + +int ringbufferPut(ringbuffer_t *handle, uint8_t *data, uint32_t dataLen) { + uint32_t freeSpace = 0; + if (handle->bufferReadIdx == handle->bufferWriteIdx) { + freeSpace = handle->bufferSize; + } else if (handle->bufferReadIdx > handle->bufferWriteIdx) { + freeSpace = handle->bufferReadIdx - handle->bufferWriteIdx; + } else { + freeSpace = (handle->bufferSize - handle->bufferWriteIdx) + handle->bufferReadIdx; + } + + if (dataLen > freeSpace) { + return -1; + } + + if (dataLen <= (handle->bufferSize - handle->bufferWriteIdx)) { + memcpy(handle->buffer + handle->bufferWriteIdx, data, dataLen); + handle->bufferWriteIdx += dataLen; + if (handle->bufferWriteIdx == handle->bufferSize) { + handle->bufferWriteIdx = 0; + } + } else { + uint32_t remainingToTop = handle->bufferSize - handle->bufferWriteIdx; + memcpy(handle->buffer + handle->bufferWriteIdx, data, remainingToTop); + memcpy(handle->buffer, data + remainingToTop, dataLen - remainingToTop); + handle->bufferWriteIdx = dataLen - remainingToTop; + } + + return 0; +} + +bool ringbufferEmpty(ringbuffer_t *handle) { + return handle->bufferReadIdx == handle->bufferWriteIdx; +} + +uint8_t *ringbufferGet(ringbuffer_t *handle, uint32_t dataLen) { + return NULL; +} + +int ringbufferGetOne(ringbuffer_t *handle) { + int res = -1; + if (! ringbufferEmpty(handle)) { + uint8_t r = *(handle->buffer + handle->bufferReadIdx); + handle->bufferReadIdx += 1; + if (handle->bufferReadIdx == handle->bufferSize) { + handle->bufferReadIdx = 0; + } + res = (int) r; + } + return res; +} + diff --git a/tests/testRingbuffer/Makefile b/tests/testRingbuffer/Makefile new file mode 100644 index 0000000..a0397fc --- /dev/null +++ b/tests/testRingbuffer/Makefile @@ -0,0 +1,17 @@ +CFLAGS=-I../../cube/User/Inc + +test: ringbuffer.o test.o + gcc -o $@ -lcunit $^ + ./test + +ringbuffer.o: ../../cube/User/Src/ringbuffer.c + gcc -c -o $@ $(CFLAGS) $^ + +test.o: test.c + gcc -c -o $@ $(CFLAGS) $^ + + +.PHONY: clean +clean: + -rm *.o test + diff --git a/tests/testRingbuffer/test.c b/tests/testRingbuffer/test.c new file mode 100644 index 0000000..2d969a8 --- /dev/null +++ b/tests/testRingbuffer/test.c @@ -0,0 +1,223 @@ +#include +#include +#include +#include + + +// #define DEBUG + +ringbuffer_t rb; + + +void printRingbuffer(ringbuffer_t *rb) { + printf("Ringbuffer:\n"); + printf(" Size: %u\n", rb->bufferSize); + printf(" ReadIdx: %u\n", rb->bufferReadIdx); + printf(" WriteIdx: %u\n", rb->bufferWriteIdx); + + for (uint32_t i = 0; i < rb->bufferSize; i++) { + printf("%02x ", rb->buffer[i]); + } + printf("\n"); +} + +int init_suite_ringbuffer(void) { + return 0; +} + +int clean_suite_ringbuffer(void) { + return 0; +} + + +void testRingbuffer0() { +#ifdef DEBUG + printf("Initialize ringbuffer\n"); +#endif + ringbufferInit(&rb, 16); +#ifdef DEBUG + printRingbuffer(&rb); +#endif + + CU_ASSERT(rb.buffer != NULL); + CU_ASSERT(rb.bufferSize == 16); + CU_ASSERT(rb.bufferWriteIdx == 0); + CU_ASSERT(rb.bufferReadIdx == 0); +} + +void testRingbuffer1() { +#ifdef DEBUG + printf("\nPut 5 chars in buffer\n"); +#endif + int r = ringbufferPut(&rb, "abcde", 5); +#ifdef DEBUG + printf("r = %d\n", r); + printRingbuffer(&rb); +#endif + + CU_ASSERT(r == 0); + CU_ASSERT(rb.buffer != NULL); + CU_ASSERT(rb.bufferSize == 16); + CU_ASSERT(rb.bufferWriteIdx == 5); + CU_ASSERT(rb.bufferReadIdx == 0); +} + +void testRingbuffer2() { +#ifdef DEBUG + printf("\nPut 5 chars in buffer\n"); +#endif + int r = ringbufferPut(&rb, "fghij", 5); +#ifdef DEBUG + printf("r = %d\n", r); + printRingbuffer(&rb); +#endif + + CU_ASSERT(r == 0); + CU_ASSERT(rb.buffer != NULL); + CU_ASSERT(rb.bufferSize == 16); + CU_ASSERT(rb.bufferWriteIdx == 10); + CU_ASSERT(rb.bufferReadIdx == 0); +} + +void testRingbuffer3() { +#ifdef DEBUG + printf("\nPut 5 chars in buffer\n"); +#endif + int r = ringbufferPut(&rb, "klmno", 5); +#ifdef DEBUG + printf("r = %d\n", r); + printRingbuffer(&rb); +#endif + + CU_ASSERT(r == 0); + CU_ASSERT(rb.buffer != NULL); + CU_ASSERT(rb.bufferSize == 16); + CU_ASSERT(rb.bufferWriteIdx == 15); + CU_ASSERT(rb.bufferReadIdx == 0); +} + +void testRingbuffer4() { +#ifdef DEBUG + printf("\nPut 5 chars in buffer\n"); +#endif + int r = ringbufferPut(&rb, "pqrst", 5); +#ifdef DEBUG + printf("r = %d\n", r); + printRingbuffer(&rb); +#endif + CU_ASSERT(r == -1); + CU_ASSERT(rb.buffer != NULL); + CU_ASSERT(rb.bufferSize == 16); + CU_ASSERT(rb.bufferWriteIdx == 15); + CU_ASSERT(rb.bufferReadIdx == 0); +} + +void testRingbuffer5() { +#ifdef DEBUG + printf("\nRead one char from buffer\n"); +#endif + int r = ringbufferGetOne(&rb); +#ifdef DEBUG + printRingbuffer(&rb); +#endif + + CU_ASSERT(r >= 0); + CU_ASSERT(rb.buffer != NULL); + CU_ASSERT(rb.bufferSize == 16); + CU_ASSERT(rb.bufferWriteIdx == 15); + CU_ASSERT(rb.bufferReadIdx == 1); + + uint8_t rr = (uint8_t) r; + CU_ASSERT(rr == 'a'); +} + +void testRingbuffer6() { +#ifdef DEBUG + printf("\nRead some char from buffer\n"); +#endif + int r = ringbufferGetOne(&rb); +#ifdef DEBUG + printRingbuffer(&rb); +#endif + + CU_ASSERT(r >= 0); + CU_ASSERT(rb.buffer != NULL); + CU_ASSERT(rb.bufferSize == 16); + CU_ASSERT(rb.bufferWriteIdx == 15); + CU_ASSERT(rb.bufferReadIdx == 2); + + uint8_t rr = (uint8_t) r; + CU_ASSERT(rr == 'b'); + + r = ringbufferGetOne(&rb); +#ifdef DEBUG + printRingbuffer(&rb); +#endif + + CU_ASSERT(r >= 0); + CU_ASSERT(rb.buffer != NULL); + CU_ASSERT(rb.bufferSize == 16); + CU_ASSERT(rb.bufferWriteIdx == 15); + CU_ASSERT(rb.bufferReadIdx == 3); + + rr = (uint8_t) r; + CU_ASSERT(rr == 'c'); + + r = ringbufferGetOne(&rb); +#ifdef DEBUG + printRingbuffer(&rb); +#endif + + CU_ASSERT(r >= 0); + CU_ASSERT(rb.buffer != NULL); + CU_ASSERT(rb.bufferSize == 16); + CU_ASSERT(rb.bufferWriteIdx == 15); + CU_ASSERT(rb.bufferReadIdx == 4); + + rr = (uint8_t) r; + CU_ASSERT(rr == 'd'); +} + +void testRingbuffer99() { +#ifdef DEBUG + printf("De-Initialize ringbuffer\n"); +#endif + ringbufferFree(&rb); +#ifdef DEBUG + printRingbuffer(&rb); +#endif + + CU_ASSERT(rb.buffer == NULL); + CU_ASSERT(rb.bufferSize == 0); + CU_ASSERT(rb.bufferWriteIdx == 0); + CU_ASSERT(rb.bufferReadIdx == 0); +} + +int main() { + if (CUE_SUCCESS != CU_initialize_registry()) + return CU_get_error(); + + CU_pSuite ringbufferSuite = CU_add_suite("Suite_Ringbuffer", init_suite_ringbuffer, clean_suite_ringbuffer); + if (NULL == ringbufferSuite) { + CU_cleanup_registry(); + return CU_get_error(); + } + + if ((NULL == CU_add_test(ringbufferSuite, "test 0 of ringbuffer, init", testRingbuffer0)) || + (NULL == CU_add_test(ringbufferSuite, "test 1 of ringbuffer", testRingbuffer1)) || + (NULL == CU_add_test(ringbufferSuite, "test 2 of ringbuffer", testRingbuffer2)) || + (NULL == CU_add_test(ringbufferSuite, "test 3 of ringbuffer", testRingbuffer3)) || + (NULL == CU_add_test(ringbufferSuite, "test 4 of ringbuffer", testRingbuffer4)) || + (NULL == CU_add_test(ringbufferSuite, "test 5 of ringbuffer", testRingbuffer5)) || + (NULL == CU_add_test(ringbufferSuite, "test 6 of ringbuffer", testRingbuffer6)) || + (NULL == CU_add_test(ringbufferSuite, "test 99 of ringbuffer, free", testRingbuffer99)) || + 0 ) { + CU_cleanup_registry(); + return CU_get_error(); + } + + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + CU_cleanup_registry(); + return CU_get_error(); +} \ No newline at end of file diff --git a/tools/startTestEnv.sh b/tools/startTestEnv.sh new file mode 100644 index 0000000..0533533 --- /dev/null +++ b/tools/startTestEnv.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run -it --rm -u ${UID} -v ${PWD}:/mnt wollud1969/build-env-c:1.1.1 bash