From 0af68991e9b7829e2046810d9d748c5a35dc437a Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 5 Jun 2016 18:06:49 +0200 Subject: Restructure stm32 project --- src/ds18b20/README | 1 - src/ds18b20/tm_stm32f4_ds18b20.c | 394 --------------------- src/ds18b20/tm_stm32f4_ds18b20.h | 317 ----------------- src/ds18b20/tm_stm32f4_onewire.c | 414 ----------------------- src/ds18b20/tm_stm32f4_onewire.h | 300 ---------------- src/fsm/.gitignore | 1 - src/fsm/Makefile | 126 ------- src/fsm/README.md | 15 - src/fsm/bin/.git_keep | 0 src/fsm/debug.c | 77 ----- src/fsm/debug.h | 47 --- src/fsm/hardfault.s | 13 - src/glutt-o-logique/FreeRTOSConfig.h | 3 + src/glutt-o-logique/Makefile | 133 ++++++++ src/glutt-o-logique/audio.c | 220 ++++++++++++ src/glutt-o-logique/common.c | 7 + src/glutt-o-logique/cw.c | 4 + src/glutt-o-logique/debug.c | 77 +++++ src/glutt-o-logique/debug.h | 47 +++ src/glutt-o-logique/delay.c | 51 +++ src/glutt-o-logique/ds18b20/README | 1 + src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.c | 394 +++++++++++++++++++++ src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.h | 317 +++++++++++++++++ src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.c | 414 +++++++++++++++++++++++ src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.h | 300 ++++++++++++++++ src/glutt-o-logique/fsm.c | 8 + src/glutt-o-logique/gps.c | 4 + src/glutt-o-logique/i2c.c | 350 +++++++++++++++++++ src/glutt-o-logique/leds.c | 42 +++ src/glutt-o-logique/leds.h | 4 + src/glutt-o-logique/main.c | 69 ++++ src/glutt-o-logique/minmea.c | 1 + src/glutt-o-logique/pio.c | 187 ++++++++++ src/glutt-o-logique/temperature.c | 93 +++++ src/glutt-o-logique/usart.c | 156 +++++++++ src/stm32f/.gitignore | 1 - src/stm32f/FreeRTOS | 1 - src/stm32f/Makefile | 131 ------- src/stm32f/bin/.gitignore | 2 - src/stm32f/bsp | 1 - src/stm32f/includes/GPIO/leds.h | 4 - src/stm32f/obj/.gitignore | 2 - src/stm32f/src/Audio/audio.c | 220 ------------ src/stm32f/src/Audio/cw.c | 4 - src/stm32f/src/Core/FreeRTOSConfig.h | 3 - src/stm32f/src/Core/common.c | 7 - src/stm32f/src/Core/delay.c | 51 --- src/stm32f/src/Core/fsm.c | 8 - src/stm32f/src/Core/main.c | 69 ---- src/stm32f/src/GPIO/i2c.c | 350 ------------------- src/stm32f/src/GPIO/leds.c | 42 --- src/stm32f/src/GPIO/pio.c | 187 ---------- src/stm32f/src/GPIO/temperature.c | 93 ----- src/stm32f/src/GPIO/tm_stm32f4_ds18b20.c | 1 - src/stm32f/src/GPIO/tm_stm32f4_ds18b20.h | 1 - src/stm32f/src/GPIO/tm_stm32f4_onewire.c | 1 - src/stm32f/src/GPIO/tm_stm32f4_onewire.h | 1 - src/stm32f/src/GPIO/usart.c | 156 --------- src/stm32f/src/GPS/gps.c | 4 - src/stm32f/src/GPS/minema.c | 1 - 60 files changed, 2882 insertions(+), 3046 deletions(-) delete mode 100644 src/ds18b20/README delete mode 100644 src/ds18b20/tm_stm32f4_ds18b20.c delete mode 100644 src/ds18b20/tm_stm32f4_ds18b20.h delete mode 100644 src/ds18b20/tm_stm32f4_onewire.c delete mode 100644 src/ds18b20/tm_stm32f4_onewire.h delete mode 100644 src/fsm/.gitignore delete mode 100644 src/fsm/Makefile delete mode 100644 src/fsm/README.md delete mode 100644 src/fsm/bin/.git_keep delete mode 100644 src/fsm/debug.c delete mode 100644 src/fsm/debug.h delete mode 100644 src/fsm/hardfault.s create mode 100644 src/glutt-o-logique/FreeRTOSConfig.h create mode 100644 src/glutt-o-logique/Makefile create mode 100644 src/glutt-o-logique/audio.c create mode 100644 src/glutt-o-logique/common.c create mode 100644 src/glutt-o-logique/cw.c create mode 100644 src/glutt-o-logique/debug.c create mode 100644 src/glutt-o-logique/debug.h create mode 100644 src/glutt-o-logique/delay.c create mode 100644 src/glutt-o-logique/ds18b20/README create mode 100644 src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.c create mode 100644 src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.h create mode 100644 src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.c create mode 100644 src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.h create mode 100644 src/glutt-o-logique/fsm.c create mode 100644 src/glutt-o-logique/gps.c create mode 100644 src/glutt-o-logique/i2c.c create mode 100644 src/glutt-o-logique/leds.c create mode 100644 src/glutt-o-logique/leds.h create mode 100644 src/glutt-o-logique/main.c create mode 100644 src/glutt-o-logique/minmea.c create mode 100644 src/glutt-o-logique/pio.c create mode 100644 src/glutt-o-logique/temperature.c create mode 100644 src/glutt-o-logique/usart.c delete mode 100644 src/stm32f/.gitignore delete mode 120000 src/stm32f/FreeRTOS delete mode 100644 src/stm32f/Makefile delete mode 100644 src/stm32f/bin/.gitignore delete mode 120000 src/stm32f/bsp delete mode 100644 src/stm32f/includes/GPIO/leds.h delete mode 100644 src/stm32f/obj/.gitignore delete mode 100644 src/stm32f/src/Audio/audio.c delete mode 100644 src/stm32f/src/Audio/cw.c delete mode 100644 src/stm32f/src/Core/FreeRTOSConfig.h delete mode 100644 src/stm32f/src/Core/common.c delete mode 100644 src/stm32f/src/Core/delay.c delete mode 100644 src/stm32f/src/Core/fsm.c delete mode 100644 src/stm32f/src/Core/main.c delete mode 100644 src/stm32f/src/GPIO/i2c.c delete mode 100644 src/stm32f/src/GPIO/leds.c delete mode 100644 src/stm32f/src/GPIO/pio.c delete mode 100644 src/stm32f/src/GPIO/temperature.c delete mode 120000 src/stm32f/src/GPIO/tm_stm32f4_ds18b20.c delete mode 120000 src/stm32f/src/GPIO/tm_stm32f4_ds18b20.h delete mode 120000 src/stm32f/src/GPIO/tm_stm32f4_onewire.c delete mode 120000 src/stm32f/src/GPIO/tm_stm32f4_onewire.h delete mode 100644 src/stm32f/src/GPIO/usart.c delete mode 100644 src/stm32f/src/GPS/gps.c delete mode 100644 src/stm32f/src/GPS/minema.c (limited to 'src') diff --git a/src/ds18b20/README b/src/ds18b20/README deleted file mode 100644 index 0cd66d5..0000000 --- a/src/ds18b20/README +++ /dev/null @@ -1 +0,0 @@ -This folder contains a library to access Dallas 1-wire temperature sensors. diff --git a/src/ds18b20/tm_stm32f4_ds18b20.c b/src/ds18b20/tm_stm32f4_ds18b20.c deleted file mode 100644 index d16e48c..0000000 --- a/src/ds18b20/tm_stm32f4_ds18b20.c +++ /dev/null @@ -1,394 +0,0 @@ -/** - * |---------------------------------------------------------------------- - * | Copyright (C) Tilen Majerle, 2014 - * | - * | This program is free software: you can redistribute it and/or modify - * | it under the terms of the GNU General Public License as published by - * | the Free Software Foundation, either version 3 of the License, or - * | any later version. - * | - * | This program is distributed in the hope that it will be useful, - * | but WITHOUT ANY WARRANTY; without even the implied warranty of - * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * | GNU General Public License for more details. - * | - * | You should have received a copy of the GNU General Public License - * | along with this program. If not, see . - * |---------------------------------------------------------------------- - */ -#include "tm_stm32f4_ds18b20.h" - -uint8_t TM_DS18B20_Start(TM_OneWire_t* OneWire, uint8_t *ROM) { - /* Check if device is DS18B20 */ - if (!TM_DS18B20_Is(ROM)) { - return 0; - } - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Start temperature conversion */ - TM_OneWire_WriteByte(OneWire, DS18B20_CMD_CONVERTTEMP); - - return 1; -} - -void TM_DS18B20_StartAll(TM_OneWire_t* OneWire) { - /* Reset pulse */ - TM_OneWire_Reset(OneWire); - /* Skip rom */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_SKIPROM); - /* Start conversion on all connected devices */ - TM_OneWire_WriteByte(OneWire, DS18B20_CMD_CONVERTTEMP); -} - -uint8_t TM_DS18B20_Read(TM_OneWire_t* OneWire, uint8_t *ROM, float *destination) { - uint16_t temperature; - uint8_t resolution; - int8_t digit, minus = 0; - float decimal; - uint8_t i = 0; - uint8_t data[9]; - uint8_t crc; - - /* Check if device is DS18B20 */ - if (!TM_DS18B20_Is(ROM)) { - return 0; - } - - /* Check if line is released, if it is, then conversion is complete */ - if (!TM_OneWire_ReadBit(OneWire)) { - /* Conversion is not finished yet */ - return 0; - } - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Read scratchpad command by onewire protocol */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); - - /* Get data */ - for (i = 0; i < 9; i++) { - /* Read byte by byte */ - data[i] = TM_OneWire_ReadByte(OneWire); - } - - /* Calculate CRC */ - crc = TM_OneWire_CRC8(data, 8); - - /* Check if CRC is ok */ - if (crc != data[8]) { - /* CRC invalid */ - return 0; - } - - /* First two bytes of scratchpad are temperature values */ - temperature = data[0] | (data[1] << 8); - - /* Reset line */ - TM_OneWire_Reset(OneWire); - - /* Check if temperature is negative */ - if (temperature & 0x8000) { - /* Two's complement, temperature is negative */ - temperature = ~temperature + 1; - minus = 1; - } - - - /* Get sensor resolution */ - resolution = ((data[4] & 0x60) >> 5) + 9; - - - /* Store temperature integer digits and decimal digits */ - digit = temperature >> 4; - digit |= ((temperature >> 8) & 0x7) << 4; - - /* Store decimal digits */ - switch (resolution) { - case 9: { - decimal = (temperature >> 3) & 0x01; - decimal *= (float)DS18B20_DECIMAL_STEPS_9BIT; - } break; - case 10: { - decimal = (temperature >> 2) & 0x03; - decimal *= (float)DS18B20_DECIMAL_STEPS_10BIT; - } break; - case 11: { - decimal = (temperature >> 1) & 0x07; - decimal *= (float)DS18B20_DECIMAL_STEPS_11BIT; - } break; - case 12: { - decimal = temperature & 0x0F; - decimal *= (float)DS18B20_DECIMAL_STEPS_12BIT; - } break; - default: { - decimal = 0xFF; - digit = 0; - } - } - - /* Check for negative part */ - decimal = digit + decimal; - if (minus) { - decimal = 0 - decimal; - } - - /* Set to pointer */ - *destination = decimal; - - /* Return 1, temperature valid */ - return 1; -} - -uint8_t TM_DS18B20_GetResolution(TM_OneWire_t* OneWire, uint8_t *ROM) { - uint8_t conf; - - if (!TM_DS18B20_Is(ROM)) { - return 0; - } - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Read scratchpad command by onewire protocol */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); - - /* Ignore first 4 bytes */ - TM_OneWire_ReadByte(OneWire); - TM_OneWire_ReadByte(OneWire); - TM_OneWire_ReadByte(OneWire); - TM_OneWire_ReadByte(OneWire); - - /* 5th byte of scratchpad is configuration register */ - conf = TM_OneWire_ReadByte(OneWire); - - /* Return 9 - 12 value according to number of bits */ - return ((conf & 0x60) >> 5) + 9; -} - -uint8_t TM_DS18B20_SetResolution(TM_OneWire_t* OneWire, uint8_t *ROM, TM_DS18B20_Resolution_t resolution) { - uint8_t th, tl, conf; - if (!TM_DS18B20_Is(ROM)) { - return 0; - } - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Read scratchpad command by onewire protocol */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); - - /* Ignore first 2 bytes */ - TM_OneWire_ReadByte(OneWire); - TM_OneWire_ReadByte(OneWire); - - th = TM_OneWire_ReadByte(OneWire); - tl = TM_OneWire_ReadByte(OneWire); - conf = TM_OneWire_ReadByte(OneWire); - - if (resolution == TM_DS18B20_Resolution_9bits) { - conf &= ~(1 << DS18B20_RESOLUTION_R1); - conf &= ~(1 << DS18B20_RESOLUTION_R0); - } else if (resolution == TM_DS18B20_Resolution_10bits) { - conf &= ~(1 << DS18B20_RESOLUTION_R1); - conf |= 1 << DS18B20_RESOLUTION_R0; - } else if (resolution == TM_DS18B20_Resolution_11bits) { - conf |= 1 << DS18B20_RESOLUTION_R1; - conf &= ~(1 << DS18B20_RESOLUTION_R0); - } else if (resolution == TM_DS18B20_Resolution_12bits) { - conf |= 1 << DS18B20_RESOLUTION_R1; - conf |= 1 << DS18B20_RESOLUTION_R0; - } - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Write scratchpad command by onewire protocol, only th, tl and conf register can be written */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_WSCRATCHPAD); - - /* Write bytes */ - TM_OneWire_WriteByte(OneWire, th); - TM_OneWire_WriteByte(OneWire, tl); - TM_OneWire_WriteByte(OneWire, conf); - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Copy scratchpad to EEPROM of DS18B20 */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_CPYSCRATCHPAD); - - return 1; -} - -uint8_t TM_DS18B20_Is(uint8_t *ROM) { - /* Checks if first byte is equal to DS18B20's family code */ - if (*ROM == DS18B20_FAMILY_CODE) { - return 1; - } - return 0; -} - -uint8_t TM_DS18B20_SetAlarmLowTemperature(TM_OneWire_t* OneWire, uint8_t *ROM, int8_t temp) { - uint8_t tl, th, conf; - if (!TM_DS18B20_Is(ROM)) { - return 0; - } - if (temp > 125) { - temp = 125; - } - if (temp < -55) { - temp = -55; - } - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Read scratchpad command by onewire protocol */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); - - /* Ignore first 2 bytes */ - TM_OneWire_ReadByte(OneWire); - TM_OneWire_ReadByte(OneWire); - - th = TM_OneWire_ReadByte(OneWire); - tl = TM_OneWire_ReadByte(OneWire); - conf = TM_OneWire_ReadByte(OneWire); - - tl = (uint8_t)temp; - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Write scratchpad command by onewire protocol, only th, tl and conf register can be written */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_WSCRATCHPAD); - - /* Write bytes */ - TM_OneWire_WriteByte(OneWire, th); - TM_OneWire_WriteByte(OneWire, tl); - TM_OneWire_WriteByte(OneWire, conf); - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Copy scratchpad to EEPROM of DS18B20 */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_CPYSCRATCHPAD); - - return 1; -} - -uint8_t TM_DS18B20_SetAlarmHighTemperature(TM_OneWire_t* OneWire, uint8_t *ROM, int8_t temp) { - uint8_t tl, th, conf; - if (!TM_DS18B20_Is(ROM)) { - return 0; - } - if (temp > 125) { - temp = 125; - } - if (temp < -55) { - temp = -55; - } - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Read scratchpad command by onewire protocol */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); - - /* Ignore first 2 bytes */ - TM_OneWire_ReadByte(OneWire); - TM_OneWire_ReadByte(OneWire); - - th = TM_OneWire_ReadByte(OneWire); - tl = TM_OneWire_ReadByte(OneWire); - conf = TM_OneWire_ReadByte(OneWire); - - th = (uint8_t)temp; - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Write scratchpad command by onewire protocol, only th, tl and conf register can be written */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_WSCRATCHPAD); - - /* Write bytes */ - TM_OneWire_WriteByte(OneWire, th); - TM_OneWire_WriteByte(OneWire, tl); - TM_OneWire_WriteByte(OneWire, conf); - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Copy scratchpad to EEPROM of DS18B20 */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_CPYSCRATCHPAD); - - return 1; -} - -uint8_t TM_DS18B20_DisableAlarmTemperature(TM_OneWire_t* OneWire, uint8_t *ROM) { - uint8_t tl, th, conf; - if (!TM_DS18B20_Is(ROM)) { - return 0; - } - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Read scratchpad command by onewire protocol */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); - - /* Ignore first 2 bytes */ - TM_OneWire_ReadByte(OneWire); - TM_OneWire_ReadByte(OneWire); - - th = TM_OneWire_ReadByte(OneWire); - tl = TM_OneWire_ReadByte(OneWire); - conf = TM_OneWire_ReadByte(OneWire); - - th = 125; - tl = (uint8_t)-55; - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Write scratchpad command by onewire protocol, only th, tl and conf register can be written */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_WSCRATCHPAD); - - /* Write bytes */ - TM_OneWire_WriteByte(OneWire, th); - TM_OneWire_WriteByte(OneWire, tl); - TM_OneWire_WriteByte(OneWire, conf); - - /* Reset line */ - TM_OneWire_Reset(OneWire); - /* Select ROM number */ - TM_OneWire_SelectWithPointer(OneWire, ROM); - /* Copy scratchpad to EEPROM of DS18B20 */ - TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_CPYSCRATCHPAD); - - return 1; -} - -uint8_t TM_DS18B20_AlarmSearch(TM_OneWire_t* OneWire) { - /* Start alarm search */ - return TM_OneWire_Search(OneWire, DS18B20_CMD_ALARMSEARCH); -} - -uint8_t TM_DS18B20_AllDone(TM_OneWire_t* OneWire) { - /* If read bit is low, then device is not finished yet with calculation temperature */ - return TM_OneWire_ReadBit(OneWire); -} - - diff --git a/src/ds18b20/tm_stm32f4_ds18b20.h b/src/ds18b20/tm_stm32f4_ds18b20.h deleted file mode 100644 index 337883e..0000000 --- a/src/ds18b20/tm_stm32f4_ds18b20.h +++ /dev/null @@ -1,317 +0,0 @@ -/** - * @author Tilen Majerle - * @email tilen@majerle.eu - * @website http://stm32f4-discovery.com - * @link http://stm32f4-discovery.com/2014/05/13-reading-temperature-with-dallas-ds18b20-on-stm32f429-discovery-board/ - * @version v2.0 - * @ide Keil uVision - * @license GNU GPL v3 - * @brief Library for interfacing DS18B20 temperature sensor from Dallas semiconductors. - * -@verbatim - ---------------------------------------------------------------------- - Copyright (C) Tilen Majerle, 2015 - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - ---------------------------------------------------------------------- -@endverbatim - */ -/** - * Library for interfacing DS18B20 temperature sensor from Dallas semiconductors. - * - * @author Tilen Majerle - * @email tilen@majerle.eu - * @website http://stm32f4-discovery.com - * @link http://stm32f4-discovery.com/2014/05/13-reading-temperature-with-dallas-ds18b20-on-stm32f429-discovery-board/ - * @version v2.0 - * @ide Keil uVision - * @license GNU GPL v3 - * - * |---------------------------------------------------------------------- - * | Copyright (C) Tilen Majerle, 2014 - * | - * | This program is free software: you can redistribute it and/or modify - * | it under the terms of the GNU General Public License as published by - * | the Free Software Foundation, either version 3 of the License, or - * | any later version. - * | - * | This program is distributed in the hope that it will be useful, - * | but WITHOUT ANY WARRANTY; without even the implied warranty of - * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * | GNU General Public License for more details. - * | - * | You should have received a copy of the GNU General Public License - * | along with this program. If not, see . - * |---------------------------------------------------------------------- - * - * Version 2.0 - * - January 04, 2015 - * - New system, supporting OneWire library 2.0 - * - * Version 1.1 - * - December 06, 2014 - * - Now CRC is calculated and checked if data are valid - * - New version of OneWire library is required, download already available on stm32f4-discovery.com - * - * With this you can read temperature, set and get temperature resolution from 9 to 12 bits - * and check if device is DS18B20 - * - * Pin for STM32F4xx is the same as set with TM ONEWIRE library. - */ -#ifndef TM_DS18B20_H -#define TM_DS18B20_H 200 - -/** - * @addtogroup TM_STM32F4xx_Libraries - * @{ - */ - -/** - * @defgroup TM_DS12820 - * @brief Library for interfacing DS18B20 temperature sensor from Dallas semiconductors - http://stm32f4-discovery.com/2014/05/13-reading-temperature-with-dallas-ds18b20-on-stm32f429-discovery-board/ - * @{ - * - * With this you can read temperature, set and get temperature resolution from 9 to 12 bits and check if device is DS18B20. - * - * Pin for STM32F4xx is the same as set with TM ONEWIRE library. - * - * \par Changelog - * -@verbatim - Version 2.0 - - January 04, 2015 - - New system, supporting OneWire library 2.0 - - Version 1.1 - - December 06, 2014 - - Now CRC is calculated and checked if data are valid - - New version of OneWire library is required, download already available on stm32f4-discovery.com - - Version 1.0 - - First release -@endverbatim - * - * \par Dependencies - * -@verbatim - - STM32F4xx - - TM ONEWIRE - - TM GPIO -@endverbatim - */ - -#include "stm32f4xx.h" -#include "tm_stm32f4_onewire.h" - -/* OneWire version check */ -#if TM_ONEWIRE_H < 200 -#error "Please update TM ONEWIRE LIB, minimum required version is 2.0.0. Download available on stm32f4-discovery.com website" -#endif - -/** - * @defgroup TM_DS18B20_Macros - * @brief Library defines - * @{ - */ - -/* Every onewire chip has different ROM code, but all the same chips has same family code */ -/* in case of DS18B20 this is 0x28 and this is first byte of ROM address */ -#define DS18B20_FAMILY_CODE 0x28 -#define DS18B20_CMD_ALARMSEARCH 0xEC - -/* DS18B20 read temperature command */ -#define DS18B20_CMD_CONVERTTEMP 0x44 /* Convert temperature */ -#define DS18B20_DECIMAL_STEPS_12BIT 0.0625 -#define DS18B20_DECIMAL_STEPS_11BIT 0.125 -#define DS18B20_DECIMAL_STEPS_10BIT 0.25 -#define DS18B20_DECIMAL_STEPS_9BIT 0.5 - -/* Bits locations for resolution */ -#define DS18B20_RESOLUTION_R1 6 -#define DS18B20_RESOLUTION_R0 5 - -/* CRC enabled */ -#ifdef DS18B20_USE_CRC -#define DS18B20_DATA_LEN 9 -#else -#define DS18B20_DATA_LEN 2 -#endif - -/** - * @} - */ - -/** - * @defgroup TM_DS18B20_Typedefs - * @brief Library Typedefs - * @{ - */ - -/** - * @brief DS18B0 Resolutions available - */ -typedef enum { - TM_DS18B20_Resolution_9bits = 9, /*!< DS18B20 9 bits resolution */ - TM_DS18B20_Resolution_10bits = 10, /*!< DS18B20 10 bits resolution */ - TM_DS18B20_Resolution_11bits = 11, /*!< DS18B20 11 bits resolution */ - TM_DS18B20_Resolution_12bits = 12 /*!< DS18B20 12 bits resolution */ -} TM_DS18B20_Resolution_t; - -/** - * @} - */ - -/** - * @defgroup TM_DS18B20_Functions - * @brief Library Functions - * @{ - */ - -/** - * @brief Starts temperature conversion for specific DS18B20 on specific onewire channel - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. - * Entire ROM address is 8-bytes long - * @retval 1 if device is DS18B20 or 0 if not - */ -uint8_t TM_DS18B20_Start(TM_OneWire_t* OneWireStruct, uint8_t* ROM); - -/** - * @brief Starts temperature conversion for all DS18B20 devices on specific onewire channel - * @note This mode will skip ROM addressing - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @retval None - */ -void TM_DS18B20_StartAll(TM_OneWire_t* OneWireStruct); - -/** - * @brief Reads temperature from DS18B20 - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. - * Entire ROM address is 8-bytes long - * @param *destination: Pointer to float variable to store temperature - * @retval Temperature status: - * - 0: Device is not DS18B20 or conversion is not done yet or CRC failed - * - > 0: Temperature is read OK - */ -uint8_t TM_DS18B20_Read(TM_OneWire_t* OneWireStruct, uint8_t* ROM, float* destination); - -/** - * @brief Gets resolution for temperature conversion from DS18B20 device - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. - * Entire ROM address is 8-bytes long - * @retval Resolution: - * - 0: Device is not DS18B20 - * - 9 - 12: Resolution of DS18B20 - */ -uint8_t TM_DS18B20_GetResolution(TM_OneWire_t* OneWireStruct, uint8_t* ROM); - -/** - * @brief Sets resolution for specific DS18B20 device - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. - * Entire ROM address is 8-bytes long - * @param resolution: Resolution for DS18B20 device. This parameter can be a value of @ref TM_DS18B20_Resolution_t enumeration. - * @retval Success status: - * - 0: Device is not DS18B20 - * - > 0: Resolution set OK - */ -uint8_t TM_DS18B20_SetResolution(TM_OneWire_t* OneWireStruct, uint8_t* ROM, TM_DS18B20_Resolution_t resolution); - -/** - * @brief Checks if device with specific ROM number is DS18B20 - * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. - * Entire ROM address is 8-bytes long - * @retval Device status - * - 0: Device is not DS18B20 - * - > 0: Device is DS18B20 - */ -uint8_t TM_DS18B20_Is(uint8_t* ROM); - -/** - * @brief Sets high alarm temperature to specific DS18B20 sensor - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. - * Entire ROM address is 8-bytes long - * @param temp: integer value for temperature between -55 to 125 degrees - * @retval Success status: - * - 0: Device is not DS18B20 - * - > 0: High alarm set OK - */ -uint8_t TM_DS18B20_SetAlarmHighTemperature(TM_OneWire_t* OneWireStruct, uint8_t* ROM, int8_t temp); - -/** - * @brief Sets low alarm temperature to specific DS18B20 sensor - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. - * Entire ROM address is 8-bytes long - * @param temp: integer value for temperature between -55 to 125 degrees - * @retval Success status: - * - 0: Device is not DS18B20 - * - > 0: Low alarm set OK - */ -uint8_t TM_DS18B20_SetAlarmLowTemperature(TM_OneWire_t* OneWireStruct, uint8_t* ROM, int8_t temp); - -/** - * @brief Disables alarm temperature for specific DS18B20 sensor - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. - * Entire ROM address is 8-bytes long - * @retval Success status: - * - 0: Device is not DS18B20 - * - > 0: Alarm disabled OK - */ -uint8_t TM_DS18B20_DisableAlarmTemperature(TM_OneWire_t* OneWireStruct, uint8_t* ROM); - -/** - * @brief Searches for devices with alarm flag set - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @retval Alarm search status - * - 0: No device found with alarm flag set - * - > 0: Device is found with alarm flag - * @note To get all devices on one onewire channel with alarm flag set, you can do this: -@verbatim -while (TM_DS18B20_AlarmSearch(&OneWireStruct)) { - //Read device ID here - //Print to user device by device -} -@endverbatim - * @retval 1 if any device has flag, otherwise 0 - */ -uint8_t TM_DS18B20_AlarmSearch(TM_OneWire_t* OneWireStruct); - -/** - * @brief Checks if all DS18B20 sensors are done with temperature conversion - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) - * @retval Conversion status - * - 0: Not all devices are done - * - > 0: All devices are done with conversion - */ -uint8_t TM_DS18B20_AllDone(TM_OneWire_t* OneWireStruct); - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#endif - diff --git a/src/ds18b20/tm_stm32f4_onewire.c b/src/ds18b20/tm_stm32f4_onewire.c deleted file mode 100644 index 44ec8db..0000000 --- a/src/ds18b20/tm_stm32f4_onewire.c +++ /dev/null @@ -1,414 +0,0 @@ -/** - * |---------------------------------------------------------------------- - * | Copyright (C) Tilen Majerle, 2014 - * | - * | This program is free software: you can redistribute it and/or modify - * | it under the terms of the GNU General Public License as published by - * | the Free Software Foundation, either version 3 of the License, or - * | any later version. - * | - * | This program is distributed in the hope that it will be useful, - * | but WITHOUT ANY WARRANTY; without even the implied warranty of - * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * | GNU General Public License for more details. - * | - * | You should have received a copy of the GNU General Public License - * | along with this program. If not, see . - * |---------------------------------------------------------------------- - */ -#include "tm_stm32f4_onewire.h" - -void delay_us(uint32_t); - -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); -} - -static void -TM_GPIO_SetPinAsOutput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ -#if 0 - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - 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 - GPIO_ResetBits(GPIOx, GPIO_Pin); -} - -static int -TM_GPIO_GetInputPinValue(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - return GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) ? 1 : 0; -} - -static void -ONEWIRE_DELAY(uint32_t micros) -{ - delay_us(micros); -} - -void TM_OneWire_Init(TM_OneWire_t* OneWireStruct, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { - ONEWIRE_INPUT(OneWireStruct); - /* Save settings */ - OneWireStruct->GPIOx = GPIOx; - OneWireStruct->GPIO_Pin = GPIO_Pin; -} - -uint8_t TM_OneWire_Reset(TM_OneWire_t* OneWireStruct) { - uint8_t i; - - /* Line low, and wait 480us */ - ONEWIRE_LOW(OneWireStruct); - ONEWIRE_OUTPUT(OneWireStruct); - ONEWIRE_DELAY(480); - - /* Release line and wait for 70us */ - ONEWIRE_INPUT(OneWireStruct); - ONEWIRE_DELAY(70); - - /* Check bit value */ - i = TM_GPIO_GetInputPinValue(OneWireStruct->GPIOx, OneWireStruct->GPIO_Pin); - - /* Delay for 410 us */ - ONEWIRE_DELAY(410); - - /* Return value of presence pulse, 0 = OK, 1 = ERROR */ - return i; -} - -void TM_OneWire_WriteBit(TM_OneWire_t* OneWireStruct, uint8_t bit) { - if (bit) { - /* Set line low */ - ONEWIRE_LOW(OneWireStruct); - ONEWIRE_OUTPUT(OneWireStruct); - ONEWIRE_DELAY(10); - - /* Bit high */ - ONEWIRE_INPUT(OneWireStruct); - - /* Wait for 55 us and release the line */ - ONEWIRE_DELAY(55); - ONEWIRE_INPUT(OneWireStruct); - } else { - /* Set line low */ - ONEWIRE_LOW(OneWireStruct); - ONEWIRE_OUTPUT(OneWireStruct); - ONEWIRE_DELAY(65); - - /* Bit high */ - ONEWIRE_INPUT(OneWireStruct); - - /* Wait for 5 us and release the line */ - ONEWIRE_DELAY(5); - ONEWIRE_INPUT(OneWireStruct); - } - -} - -uint8_t TM_OneWire_ReadBit(TM_OneWire_t* OneWireStruct) { - uint8_t bit = 0; - - /* Line low */ - ONEWIRE_LOW(OneWireStruct); - ONEWIRE_OUTPUT(OneWireStruct); - ONEWIRE_DELAY(3); - - /* Release line */ - ONEWIRE_INPUT(OneWireStruct); - ONEWIRE_DELAY(10); - - /* Read line value */ - if (TM_GPIO_GetInputPinValue(OneWireStruct->GPIOx, OneWireStruct->GPIO_Pin)) { - /* Bit is HIGH */ - bit = 1; - } - - /* Wait 50us to complete 60us period */ - ONEWIRE_DELAY(50); - - /* Return bit value */ - return bit; -} - -void TM_OneWire_WriteByte(TM_OneWire_t* OneWireStruct, uint8_t byte) { - uint8_t i = 8; - /* Write 8 bits */ - while (i--) { - /* LSB bit is first */ - TM_OneWire_WriteBit(OneWireStruct, byte & 0x01); - byte >>= 1; - } -} - -uint8_t TM_OneWire_ReadByte(TM_OneWire_t* OneWireStruct) { - uint8_t i = 8, byte = 0; - while (i--) { - byte >>= 1; - byte |= (TM_OneWire_ReadBit(OneWireStruct) << 7); - } - - return byte; -} - -uint8_t TM_OneWire_First(TM_OneWire_t* OneWireStruct) { - /* Reset search values */ - TM_OneWire_ResetSearch(OneWireStruct); - - /* Start with searching */ - return TM_OneWire_Search(OneWireStruct, ONEWIRE_CMD_SEARCHROM); -} - -uint8_t TM_OneWire_Next(TM_OneWire_t* OneWireStruct) { - /* Leave the search state alone */ - return TM_OneWire_Search(OneWireStruct, ONEWIRE_CMD_SEARCHROM); -} - -void TM_OneWire_ResetSearch(TM_OneWire_t* OneWireStruct) { - /* Reset the search state */ - OneWireStruct->LastDiscrepancy = 0; - OneWireStruct->LastDeviceFlag = 0; - OneWireStruct->LastFamilyDiscrepancy = 0; -} - -uint8_t TM_OneWire_Search(TM_OneWire_t* OneWireStruct, uint8_t command) { - uint8_t id_bit_number; - uint8_t last_zero, rom_byte_number, search_result; - uint8_t id_bit, cmp_id_bit; - uint8_t rom_byte_mask, search_direction; - - /* Initialize for search */ - id_bit_number = 1; - last_zero = 0; - rom_byte_number = 0; - rom_byte_mask = 1; - search_result = 0; - - // if the last call was not the last one - if (!OneWireStruct->LastDeviceFlag) { - // 1-Wire reset - if (TM_OneWire_Reset(OneWireStruct)) { - /* Reset the search */ - OneWireStruct->LastDiscrepancy = 0; - OneWireStruct->LastDeviceFlag = 0; - OneWireStruct->LastFamilyDiscrepancy = 0; - return 0; - } - - // issue the search command - TM_OneWire_WriteByte(OneWireStruct, command); - - // loop to do the search - do { - // read a bit and its complement - id_bit = TM_OneWire_ReadBit(OneWireStruct); - cmp_id_bit = TM_OneWire_ReadBit(OneWireStruct); - - // check for no devices on 1-wire - if ((id_bit == 1) && (cmp_id_bit == 1)) { - break; - } else { - // all devices coupled have 0 or 1 - if (id_bit != cmp_id_bit) { - search_direction = id_bit; // bit write value for search - } else { - // if this discrepancy if before the Last Discrepancy - // on a previous next then pick the same as last time - if (id_bit_number < OneWireStruct->LastDiscrepancy) { - search_direction = ((OneWireStruct->ROM_NO[rom_byte_number] & rom_byte_mask) > 0); - } else { - // if equal to last pick 1, if not then pick 0 - search_direction = (id_bit_number == OneWireStruct->LastDiscrepancy); - } - - // if 0 was picked then record its position in LastZero - if (search_direction == 0) { - last_zero = id_bit_number; - - // check for Last discrepancy in family - if (last_zero < 9) { - OneWireStruct->LastFamilyDiscrepancy = last_zero; - } - } - } - - // set or clear the bit in the ROM byte rom_byte_number - // with mask rom_byte_mask - if (search_direction == 1) { - OneWireStruct->ROM_NO[rom_byte_number] |= rom_byte_mask; - } else { - OneWireStruct->ROM_NO[rom_byte_number] &= ~rom_byte_mask; - } - - // serial number search direction write bit - TM_OneWire_WriteBit(OneWireStruct, search_direction); - - // increment the byte counter id_bit_number - // and shift the mask rom_byte_mask - id_bit_number++; - rom_byte_mask <<= 1; - - // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask - if (rom_byte_mask == 0) { - //docrc8(ROM_NO[rom_byte_number]); // accumulate the CRC - rom_byte_number++; - rom_byte_mask = 1; - } - } - } while (rom_byte_number < 8); // loop until through all ROM bytes 0-7 - - // if the search was successful then - if (!(id_bit_number < 65)) { - // search successful so set LastDiscrepancy,LastDeviceFlag,search_result - OneWireStruct->LastDiscrepancy = last_zero; - - // check for last device - if (OneWireStruct->LastDiscrepancy == 0) { - OneWireStruct->LastDeviceFlag = 1; - } - - search_result = 1; - } - } - - // if no device found then reset counters so next 'search' will be like a first - if (!search_result || !OneWireStruct->ROM_NO[0]) { - OneWireStruct->LastDiscrepancy = 0; - OneWireStruct->LastDeviceFlag = 0; - OneWireStruct->LastFamilyDiscrepancy = 0; - search_result = 0; - } - - return search_result; -} - -int TM_OneWire_Verify(TM_OneWire_t* OneWireStruct) { - unsigned char rom_backup[8]; - int i,rslt,ld_backup,ldf_backup,lfd_backup; - - // keep a backup copy of the current state - for (i = 0; i < 8; i++) - rom_backup[i] = OneWireStruct->ROM_NO[i]; - ld_backup = OneWireStruct->LastDiscrepancy; - ldf_backup = OneWireStruct->LastDeviceFlag; - lfd_backup = OneWireStruct->LastFamilyDiscrepancy; - - // set search to find the same device - OneWireStruct->LastDiscrepancy = 64; - OneWireStruct->LastDeviceFlag = 0; - - if (TM_OneWire_Search(OneWireStruct, ONEWIRE_CMD_SEARCHROM)) { - // check if same device found - rslt = 1; - for (i = 0; i < 8; i++) { - if (rom_backup[i] != OneWireStruct->ROM_NO[i]) { - rslt = 1; - break; - } - } - } else { - rslt = 0; - } - - // restore the search state - for (i = 0; i < 8; i++) { - OneWireStruct->ROM_NO[i] = rom_backup[i]; - } - OneWireStruct->LastDiscrepancy = ld_backup; - OneWireStruct->LastDeviceFlag = ldf_backup; - OneWireStruct->LastFamilyDiscrepancy = lfd_backup; - - // return the result of the verify - return rslt; -} - -void TM_OneWire_TargetSetup(TM_OneWire_t* OneWireStruct, uint8_t family_code) { - uint8_t i; - - // set the search state to find SearchFamily type devices - OneWireStruct->ROM_NO[0] = family_code; - for (i = 1; i < 8; i++) { - OneWireStruct->ROM_NO[i] = 0; - } - - OneWireStruct->LastDiscrepancy = 64; - OneWireStruct->LastFamilyDiscrepancy = 0; - OneWireStruct->LastDeviceFlag = 0; -} - -void TM_OneWire_FamilySkipSetup(TM_OneWire_t* OneWireStruct) { - // set the Last discrepancy to last family discrepancy - OneWireStruct->LastDiscrepancy = OneWireStruct->LastFamilyDiscrepancy; - OneWireStruct->LastFamilyDiscrepancy = 0; - - // check for end of list - if (OneWireStruct->LastDiscrepancy == 0) { - OneWireStruct->LastDeviceFlag = 1; - } -} - -uint8_t TM_OneWire_GetROM(TM_OneWire_t* OneWireStruct, uint8_t index) { - return OneWireStruct->ROM_NO[index]; -} - -void TM_OneWire_Select(TM_OneWire_t* OneWireStruct, uint8_t* addr) { - uint8_t i; - TM_OneWire_WriteByte(OneWireStruct, ONEWIRE_CMD_MATCHROM); - - for (i = 0; i < 8; i++) { - TM_OneWire_WriteByte(OneWireStruct, *(addr + i)); - } -} - -void TM_OneWire_SelectWithPointer(TM_OneWire_t* OneWireStruct, uint8_t *ROM) { - uint8_t i; - TM_OneWire_WriteByte(OneWireStruct, ONEWIRE_CMD_MATCHROM); - - for (i = 0; i < 8; i++) { - TM_OneWire_WriteByte(OneWireStruct, *(ROM + i)); - } -} - -void TM_OneWire_GetFullROM(TM_OneWire_t* OneWireStruct, uint8_t *firstIndex) { - uint8_t i; - for (i = 0; i < 8; i++) { - *(firstIndex + i) = OneWireStruct->ROM_NO[i]; - } -} - -uint8_t TM_OneWire_CRC8(uint8_t *addr, uint8_t len) { - uint8_t crc = 0, inbyte, i, mix; - - while (len--) { - inbyte = *addr++; - for (i = 8; i; i--) { - mix = (crc ^ inbyte) & 0x01; - crc >>= 1; - if (mix) { - crc ^= 0x8C; - } - inbyte >>= 1; - } - } - - /* Return calculated CRC */ - return crc; -} diff --git a/src/ds18b20/tm_stm32f4_onewire.h b/src/ds18b20/tm_stm32f4_onewire.h deleted file mode 100644 index 9b14109..0000000 --- a/src/ds18b20/tm_stm32f4_onewire.h +++ /dev/null @@ -1,300 +0,0 @@ -/** - * @author Tilen Majerle - * @email tilen@majerle.eu - * @website http://stm32f4-discovery.com - * @link http://stm32f4-discovery.com/2014/05/library-12-onewire-library-for-stm43f4xx/ - * @version v2.1 - * @ide Keil uVision - * @license GNU GPL v3 - * @brief Onewire library for STM32F4 devices - * -@verbatim - ---------------------------------------------------------------------- - Copyright (C) Tilen Majerle, 2015 - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - ---------------------------------------------------------------------- -@endverbatim - */ -#ifndef TM_ONEWIRE_H -#define TM_ONEWIRE_H 210 - -/* C++ detection */ -#ifdef __cplusplus -extern C { -#endif - -/** - * @addtogroup TM_STM32F4xx_Libraries - * @{ - */ - -/** - * @defgroup TM_ONEWIRE - * @brief Onewire library for STM32F4 devices - http://stm32f4-discovery.com/2014/05/library-12-onewire-library-for-stm43f4xx/ - * @{ - * - * As of version 2.0 you can now use more than just one one-wire "port" on STM32F4. This allows you to group devices to separate ports. - * - * Because if you have a loot devices on one port, if one device fail, everything is failed. You can prevent this by use more than just one port. - * - * To set your port and pin for OneWire protocol, you can do this when calling @ref TM_OneWire_Init function. - * - * \par Changelog - * -@verbatim - Version 2.1 - - March 10, 2015 - - Added support for new GPIO library - - Version 2.0 - - January 04, 2015 - - New OneWire system - - With support for multiple OneWire ports to separate group of devices - - Version 1.1 - - December 06, 2014 - - Added 8-bit CRC calculation for 1-Wire devices, algorithm from Dallas - - Version 1.0 - - First release -@endverbatim - * - * \par Dependencies - * -@verbatim - - STM32F4xx - - STM32F4xx RCC - - STM32F4xx GPIO - - TM GPIO -@endverbatim - */ -#include "stm32f4xx.h" -#include "stm32f4xx_rcc.h" -#include "stm32f4xx_gpio.h" - -/** - * @defgroup TM_ONEWIRE_Macros - * @brief Library defines - * @{ - */ - -/* Pin settings */ - -#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) - -/* OneWire commands */ -#define ONEWIRE_CMD_RSCRATCHPAD 0xBE -#define ONEWIRE_CMD_WSCRATCHPAD 0x4E -#define ONEWIRE_CMD_CPYSCRATCHPAD 0x48 -#define ONEWIRE_CMD_RECEEPROM 0xB8 -#define ONEWIRE_CMD_RPWRSUPPLY 0xB4 -#define ONEWIRE_CMD_SEARCHROM 0xF0 -#define ONEWIRE_CMD_READROM 0x33 -#define ONEWIRE_CMD_MATCHROM 0x55 -#define ONEWIRE_CMD_SKIPROM 0xCC - -/** - * @} - */ - -/** - * @defgroup TM_ONEWIRE_Typedefs - * @brief Library Typedefs - * @{ - */ - -/** - * @brief OneWire working struct - * @note Except ROM_NO member, everything is fully private and should not be touched by user - */ -typedef struct { - GPIO_TypeDef* GPIOx; /*!< GPIOx port to be used for I/O functions */ - uint16_t GPIO_Pin; /*!< GPIO Pin to be used for I/O functions */ - uint8_t LastDiscrepancy; /*!< Search private */ - uint8_t LastFamilyDiscrepancy; /*!< Search private */ - uint8_t LastDeviceFlag; /*!< Search private */ - uint8_t ROM_NO[8]; /*!< 8-bytes address of last search device */ -} TM_OneWire_t; - -/** - * @} - */ - -/** - * @defgroup TM_ONEWIRE_Functions - * @brief Library Functions - * @{ - */ - -/** - * @brief Initializes OneWire bus - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t empty working onewire structure - * @param *Pointer to GPIO port used for onewire channel - * @param GPIO_Pin: GPIO Pin on specific GPIOx to be used for onewire channel - * @retval None - */ -void TM_OneWire_Init(TM_OneWire_t* OneWireStruct, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); - -/** - * @brief Resets OneWire bus - * - * @note Sends reset command for OneWire - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure - * @retval None - */ -uint8_t TM_OneWire_Reset(TM_OneWire_t* OneWireStruct); - -/** - * @brief Reads byte from one wire bus - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure - * @retval Byte from read operation - */ -uint8_t TM_OneWire_ReadByte(TM_OneWire_t* OneWireStruct); - -/** - * @brief Writes byte to bus - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure - * @param byte: 8-bit value to write over OneWire protocol - * @retval None - */ -void TM_OneWire_WriteByte(TM_OneWire_t* OneWireStruct, uint8_t byte); - -/** - * @brief Writes single bit to onewire bus - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure - * @param bit: Bit value to send, 1 or 0 - * @retval None - */ -void TM_OneWire_WriteBit(TM_OneWire_t* OneWireStruct, uint8_t bit); - -/** - * @brief Reads single bit from one wire bus - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure - * @retval Bit value: - * - 0: Bit is low (zero) - * - > 0: Bit is high (one) - */ -uint8_t TM_OneWire_ReadBit(TM_OneWire_t* OneWireStruct); - -/** - * @brief Searches for OneWire devices on specific Onewire port - * @note Not meant for public use. Use @ref TM_OneWire_First and @ref TM_OneWire_Next for this. - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure where to search - * @param Device status: - * - 0: No devices detected - * - > 0: Device detected - */ -uint8_t TM_OneWire_Search(TM_OneWire_t* OneWireStruct, uint8_t command); - -/** - * @brief Resets search states - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire where to reset search values - * @retval None - */ -void TM_OneWire_ResetSearch(TM_OneWire_t* OneWireStruct); - -/** - * @brief Starts search, reset states first - * @note When you want to search for ALL devices on one onewire port, you should first use this function. -@verbatim -/...Initialization before -status = TM_OneWire_First(&OneWireStruct); -while (status) { - //Save ROM number from device - TM_OneWire_GetFullROM(ROM_Array_Pointer); - //Check for new device - status = TM_OneWire_Next(&OneWireStruct); -} -@endverbatim - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire where to reset search values - * @param Device status: - * - 0: No devices detected - * - > 0: Device detected - */ -uint8_t TM_OneWire_First(TM_OneWire_t* OneWireStruct); - -/** - * @brief Reads next device - * @note Use @ref TM_OneWire_First to start searching - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire - * @param Device status: - * - 0: No devices detected any more - * - > 0: New device detected - */ -uint8_t TM_OneWire_Next(TM_OneWire_t* OneWireStruct); - -/** - * @brief Gets ROM number from device from search - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire - * @param index: Because each device has 8-bytes long ROm address, you have to call this 8 times, to get ROM bytes from 0 to 7 - * @reetval ROM byte for index (0 to 7) at current found device - */ -uint8_t TM_OneWire_GetROM(TM_OneWire_t* OneWireStruct, uint8_t index); - -/** - * @brief Gets all 8 bytes ROM value from device from search - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire - * @param *firstIndex: Pointer to first location for first byte, other bytes are automatically incremented - * @retval None - */ -void TM_OneWire_GetFullROM(TM_OneWire_t* OneWireStruct, uint8_t *firstIndex); - -/** - * @brief Selects specific slave on bus - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire - * @param *addr: Pointer to first location of 8-bytes long ROM address - * @retval None - */ -void TM_OneWire_Select(TM_OneWire_t* OneWireStruct, uint8_t* addr); - -/** - * @brief Selects specific slave on bus with pointer address - * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire - * @param *ROM: Pointer to first byte of ROM address - * @retval None - */ -void TM_OneWire_SelectWithPointer(TM_OneWire_t* OneWireStruct, uint8_t* ROM); - -/** - * @brief Calculates 8-bit CRC for 1-wire devices - * @param *addr: Pointer to 8-bit array of data to calculate CRC - * @param len: Number of bytes to check - * - * @retval Calculated CRC from input data - */ -uint8_t TM_OneWire_CRC8(uint8_t* addr, uint8_t len); - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/* C++ detection */ -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/fsm/.gitignore b/src/fsm/.gitignore deleted file mode 100644 index 6533942..0000000 --- a/src/fsm/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vc.h diff --git a/src/fsm/Makefile b/src/fsm/Makefile deleted file mode 100644 index b939934..0000000 --- a/src/fsm/Makefile +++ /dev/null @@ -1,126 +0,0 @@ -### -# 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 $(INC) - $(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 - echo >> vc.h - echo >> 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/fsm/README.md b/src/fsm/README.md deleted file mode 100644 index 69f1f22..0000000 --- a/src/fsm/README.md +++ /dev/null @@ -1,15 +0,0 @@ -An example program that tries to output CW using -the audio codec on the STM32F4DISCOVERY, using the FSM -and switches. - -Connections as follows: - -Blue in QRP_n PC1 -Violet out LED red PC2 -Grey in 1750 PC4 -White out LED yel PC5 -Black - GND GND -Brown in RX_n PC6 -Red in U_n PC8 -Orange out LED grn PC9 -Green in D_n PC11 diff --git a/src/fsm/bin/.git_keep b/src/fsm/bin/.git_keep deleted file mode 100644 index e69de29..0000000 diff --git a/src/fsm/debug.c b/src/fsm/debug.c deleted file mode 100644 index 2e33a32..0000000 --- a/src/fsm/debug.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015 Matthias P. Braendli - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*/ - -#include -#include - -#include "debug.h" - -#if _DEBUG - -void debug_send_command(int command, void *message) -{ - __asm__ volatile ( - "mov r0, %[cmd];" - "mov r1, %[msg];" - "bkpt #0xAB" - : - : [cmd] "r" (command), [msg] "r" (message) - : "r0", "r1", "memory"); -} - -void put_char(char c) -{ - __asm__ volatile ( - "mov r0, #0x03\n" /* SYS_WRITEC */ - "mov r1, %[msg]\n" - "bkpt #0xAB\n" - : - : [msg] "r" (&c) - : "r0", "r1" - ); -} - -void debug_print(const char* str) -{ - const int std_err = 2; - - int strlen = 0; - const char* s; - s = str; - while (*s) { - strlen++; - s++; - } - - uint32_t m[] = { std_err, (uint32_t)str, strlen }; - debug_send_command(0x05, m); -} - -#else -void debug_send_command(int command, void *message) { } -void put_char(char c) { } -void debug_print(const char* str) { } - -#endif - diff --git a/src/fsm/debug.h b/src/fsm/debug.h deleted file mode 100644 index 6215e5f..0000000 --- a/src/fsm/debug.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015 Matthias P. Braendli - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*/ - -/* Debugging utilities using the ARM semihosting facilities. Warning, it's quite - * slow. - * - * when used with OpenOCD's gdb server, requires the gdb command - * - * monitor arm semihosting enable - */ -#ifndef __DEBUG_H_ -#define __DEBUG_H_ - -/* Example usage for the send_command function -const char *s = "Hello world\n"; -uint32_t m[] = { 2, (uint32_t)s, sizeof(s)/sizeof(char) }; -send_command(0x05, m); -// some interrupt ID - -*/ - -/* Print a string to the OpenOCD console */ -void debug_print(const char* str); - -#endif // __DEBUG_H_ - diff --git a/src/fsm/hardfault.s b/src/fsm/hardfault.s deleted file mode 100644 index 8570dcc..0000000 --- a/src/fsm/hardfault.s +++ /dev/null @@ -1,13 +0,0 @@ -.syntax unified -.cpu cortex-m3 -.thumb - -.global HardFault_Handler -.extern hard_fault_handler_c - -HardFault_Handler: - tst lr, #4 - ite eq - mrseq r0, msp - mrsne r0, psp - b hard_fault_handler_c diff --git a/src/glutt-o-logique/FreeRTOSConfig.h b/src/glutt-o-logique/FreeRTOSConfig.h new file mode 100644 index 0000000..8d6f128 --- /dev/null +++ b/src/glutt-o-logique/FreeRTOSConfig.h @@ -0,0 +1,3 @@ +#include "../../../common/src/Core/FreeRTOSConfig.h" + +#define configCHECK_FOR_STACK_OVERFLOW 2 // Default: 2 diff --git a/src/glutt-o-logique/Makefile b/src/glutt-o-logique/Makefile new file mode 100644 index 0000000..d9ff944 --- /dev/null +++ b/src/glutt-o-logique/Makefile @@ -0,0 +1,133 @@ +### +# 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=. + +SOURCES=$(shell find -L $(SRCDIR) -name '*.s') +SOURCES+=$(shell find -L $(SRCDIR) -name '*.c') +HEADERS=$(shell find -L $(SRCDIR) -name '*.h') + +INC=$(shell find -L $(SRCDIR) -name '*.h' -exec dirname {} \; | uniq) +INC+=../common/includes +INCLUDES=$(INC:%=-I%) + +# Create object list +OBJECTS=$(SOURCES:%.c=obj/%.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= $(SRCDIR)/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): vc.h $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + $(SIZE) $(BINDIR)/$(BINELF) + +dir_guard=@mkdir -p $(@D) + +obj/%.o: %.c $(HEADERS) + $(dir_guard) + @echo [CC] $< + @$(CC) $(CFLAGS) $< -o $@ + +obj/%.o: %.s $(HEADERS) + $(dir_guard) + @echo [AS] $< + @$(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 + echo >> vc.h + echo >> 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/glutt-o-logique/audio.c b/src/glutt-o-logique/audio.c new file mode 100644 index 0000000..bdb2961 --- /dev/null +++ b/src/glutt-o-logique/audio.c @@ -0,0 +1,220 @@ +#include "GPIO/i2c.h" +#include "stm32f4xx_conf.h" +#include "stm32f4xx.h" + +#include "../../../common/src/Audio/audio.c" + +void audio_initialize_platform(int plln, int pllr, int i2sdiv, int i2sodd, int rate) { + + GPIO_InitTypeDef GPIO_InitStructure; + + // Turn on peripherals. + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); + + // Assume I2C is set up + + // Configure reset pin. + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOD, &GPIO_InitStructure); + + // Configure I2S MCK, SCK, SD pins. + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_10 | GPIO_Pin_12; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOC, &GPIO_InitStructure); + + GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_SPI3); + GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3); + GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3); + + // Configure I2S WS pin. + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_SPI3); + + // Reset the codec. + GPIO_ResetBits(GPIOD, GPIO_Pin_4); + for (volatile int i = 0; i < 0x4fff; i++) { + __asm__ volatile("nop"); + } + GPIO_SetBits(GPIOD, GPIO_Pin_4); + + // Configure codec. + audio_write_register(0x02, 0x01); // Keep codec powered off. + audio_write_register(0x04, 0xaf); // SPK always off and HP always on. + + audio_write_register(0x05, 0x81); // Clock configuration: Auto detection. + audio_write_register(0x06, 0x04); // Set slave mode and Philips audio standard. + + // Power on the codec. + audio_write_register(0x02, 0x9e); + + // Configure codec for fast shutdown. + audio_write_register(0x0a, 0x00); // Disable the analog soft ramp. + audio_write_register(0x0e, 0x04); // Disable the digital soft ramp. + + audio_write_register(0x27, 0x00); // Disable the limiter attack level. + audio_write_register(0x1f, 0x0f); // Adjust bass and treble levels. + + audio_write_register(0x1a, 0x0a); // Adjust PCM volume level. + audio_write_register(0x1b, 0x0a); + + // Disable I2S. + SPI3 ->I2SCFGR = 0; + + // I2S clock configuration + RCC ->CFGR &= ~RCC_CFGR_I2SSRC; // PLLI2S clock used as I2S clock source. + RCC ->PLLI2SCFGR = (pllr << 28) | (plln << 6); + + // Enable PLLI2S and wait until it is ready. + RCC ->CR |= RCC_CR_PLLI2SON; + while (!(RCC ->CR & RCC_CR_PLLI2SRDY )) + ; + + // Configure I2S. + SPI3 ->I2SPR = i2sdiv | (i2sodd << 8) | SPI_I2SPR_MCKOE; + SPI3 ->I2SCFGR = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1 + | SPI_I2SCFGR_I2SE; // Master transmitter, Phillips mode, 16 bit values, clock polarity low, enable. + +} + +void audio_on() { + audio_write_register(0x02, 0x9e); + SPI3 ->I2SCFGR = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1 + | SPI_I2SCFGR_I2SE; // Master transmitter, Phillips mode, 16 bit values, clock polarity low, enable. +} + +void audio_off() { + audio_write_register(0x02, 0x9f); + SPI3 ->I2SCFGR = 0; +} + +void audio_set_volume(int volume) { + audio_write_register(0x20, (volume + 0x19) & 0xff); + audio_write_register(0x21, (volume + 0x19) & 0xff); +} + +void audio_output_sample(int16_t sample) { + while (!(SPI3 ->SR & SPI_SR_TXE )) + ; + SPI3 ->DR = sample; +} + + +void audio_output_sample_without_blocking(int16_t sample) { + SPI3 ->DR = sample; +} + +void audio_play_with_callback(AudioCallbackFunction *callback, void *context) { + audio_stop_dma(); + + NVIC_EnableIRQ(DMA1_Stream7_IRQn); + NVIC_SetPriority(DMA1_Stream7_IRQn, 5); + + SPI3 ->CR2 |= SPI_CR2_TXDMAEN; // Enable I2S TX DMA request. + + callback_function = callback; + callback_context = context; + buffer_number = 0; + + if (callback_function) + callback_function(callback_context, buffer_number); +} + +void audio_stop() { + audio_stop_dma(); + SPI3 ->CR2 &= ~SPI_CR2_TXDMAEN; // Disable I2S TX DMA request. + NVIC_DisableIRQ(DMA1_Stream7_IRQn); + callback_function = NULL; +} + +void audio_provide_buffer(void *samples, int numsamples) { + while (!audio_provide_buffer_without_blocking(samples, numsamples)) + __asm__ volatile ("wfi"); +} + +bool audio_provide_buffer_without_blocking(void *samples, int numsamples) { + if (next_buffer_samples) + return false; + + NVIC_DisableIRQ(DMA1_Stream7_IRQn); + + next_buffer_samples = samples; + next_buffer_length = numsamples; + + if (!dma_running) + audio_start_dma_and_request_buffers(); + + NVIC_EnableIRQ(DMA1_Stream7_IRQn); + + return true; +} + +static void audio_start_dma_and_request_buffers() { + // Configure DMA stream. + DMA1_Stream7 ->CR = (0 * DMA_SxCR_CHSEL_0 ) | // Channel 0 + (1 * DMA_SxCR_PL_0 ) | // Priority 1 + (1 * DMA_SxCR_PSIZE_0 ) | // PSIZE = 16 bit + (1 * DMA_SxCR_MSIZE_0 ) | // MSIZE = 16 bit + DMA_SxCR_MINC | // Increase memory address + (1 * DMA_SxCR_DIR_0 ) | // Memory to peripheral + DMA_SxCR_TCIE; // Transfer complete interrupt + DMA1_Stream7 ->NDTR = next_buffer_length; + DMA1_Stream7 ->PAR = (uint32_t) &SPI3 ->DR; + DMA1_Stream7 ->M0AR = (uint32_t) next_buffer_samples; + DMA1_Stream7 ->FCR = DMA_SxFCR_DMDIS; + DMA1_Stream7 ->CR |= DMA_SxCR_EN; + + // Update state. + next_buffer_samples = NULL; + buffer_number ^= 1; + dma_running = true; + + // Invoke callback if it exists to queue up another buffer. + if (callback_function) + callback_function(callback_context, buffer_number); +} + +static void audio_stop_dma() { + DMA1_Stream7 ->CR &= ~DMA_SxCR_EN; // Disable DMA stream. + while (DMA1_Stream7 ->CR & DMA_SxCR_EN ) + ; // Wait for DMA stream to stop. + + dma_running = false; +} + +void DMA1_Stream7_IRQHandler() { + DMA1 ->HIFCR |= DMA_HIFCR_CTCIF7; // Clear interrupt flag. + + if (next_buffer_samples) { + audio_start_dma_and_request_buffers(); + } else { + dma_running = false; + } +} + +// Warning: don't i2c_write call from IRQ handler ! +static void audio_write_register(uint8_t address, uint8_t value) +{ + const uint8_t device = 0x4a; + const uint8_t data[2] = {address, value}; + i2c_transaction_start(); + i2c_write(device, data, 2); + i2c_transaction_end(); +} + diff --git a/src/glutt-o-logique/common.c b/src/glutt-o-logique/common.c new file mode 100644 index 0000000..a647d26 --- /dev/null +++ b/src/glutt-o-logique/common.c @@ -0,0 +1,7 @@ +#include + +#include "../../../common/src/Core/common.c" + +void hard_fault_handler_extra() { + usart_debug("SCB_SHCSR = %x\n", SCB->SHCSR); +} diff --git a/src/glutt-o-logique/cw.c b/src/glutt-o-logique/cw.c new file mode 100644 index 0000000..028ae82 --- /dev/null +++ b/src/glutt-o-logique/cw.c @@ -0,0 +1,4 @@ +#include "../../../common/src/Audio/cw.c" + +void cw_message_sent(const char* str) { +} diff --git a/src/glutt-o-logique/debug.c b/src/glutt-o-logique/debug.c new file mode 100644 index 0000000..2e33a32 --- /dev/null +++ b/src/glutt-o-logique/debug.c @@ -0,0 +1,77 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Matthias P. Braendli + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + +#include +#include + +#include "debug.h" + +#if _DEBUG + +void debug_send_command(int command, void *message) +{ + __asm__ volatile ( + "mov r0, %[cmd];" + "mov r1, %[msg];" + "bkpt #0xAB" + : + : [cmd] "r" (command), [msg] "r" (message) + : "r0", "r1", "memory"); +} + +void put_char(char c) +{ + __asm__ volatile ( + "mov r0, #0x03\n" /* SYS_WRITEC */ + "mov r1, %[msg]\n" + "bkpt #0xAB\n" + : + : [msg] "r" (&c) + : "r0", "r1" + ); +} + +void debug_print(const char* str) +{ + const int std_err = 2; + + int strlen = 0; + const char* s; + s = str; + while (*s) { + strlen++; + s++; + } + + uint32_t m[] = { std_err, (uint32_t)str, strlen }; + debug_send_command(0x05, m); +} + +#else +void debug_send_command(int command, void *message) { } +void put_char(char c) { } +void debug_print(const char* str) { } + +#endif + diff --git a/src/glutt-o-logique/debug.h b/src/glutt-o-logique/debug.h new file mode 100644 index 0000000..6215e5f --- /dev/null +++ b/src/glutt-o-logique/debug.h @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Matthias P. Braendli + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + +/* Debugging utilities using the ARM semihosting facilities. Warning, it's quite + * slow. + * + * when used with OpenOCD's gdb server, requires the gdb command + * + * monitor arm semihosting enable + */ +#ifndef __DEBUG_H_ +#define __DEBUG_H_ + +/* Example usage for the send_command function +const char *s = "Hello world\n"; +uint32_t m[] = { 2, (uint32_t)s, sizeof(s)/sizeof(char) }; +send_command(0x05, m); +// some interrupt ID + +*/ + +/* Print a string to the OpenOCD console */ +void debug_print(const char* str); + +#endif // __DEBUG_H_ + diff --git a/src/glutt-o-logique/delay.c b/src/glutt-o-logique/delay.c new file mode 100644 index 0000000..af959f7 --- /dev/null +++ b/src/glutt-o-logique/delay.c @@ -0,0 +1,51 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 Matthias P. Braendli, Maximilien Cuony + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + +#include "Core/delay.h" +#include "stm32f4xx_conf.h" +#include "stm32f4xx.h" + +uint32_t delay_multiplier = 1; + +void delay_us(uint32_t micros) +{ + micros = micros * delay_multiplier - 10; + while (micros--); +} + +void delay_ms(uint32_t millis) +{ + for (int i = 0; i < 1000; i++) { + delay_us(millis); + } +} + +void delay_init() +{ + RCC_ClocksTypeDef RCC_Clocks; + RCC_GetClocksFreq(&RCC_Clocks); + + delay_multiplier = RCC_Clocks.HCLK_Frequency / 4000000; +} + diff --git a/src/glutt-o-logique/ds18b20/README b/src/glutt-o-logique/ds18b20/README new file mode 100644 index 0000000..0cd66d5 --- /dev/null +++ b/src/glutt-o-logique/ds18b20/README @@ -0,0 +1 @@ +This folder contains a library to access Dallas 1-wire temperature sensors. diff --git a/src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.c b/src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.c new file mode 100644 index 0000000..d16e48c --- /dev/null +++ b/src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.c @@ -0,0 +1,394 @@ +/** + * |---------------------------------------------------------------------- + * | Copyright (C) Tilen Majerle, 2014 + * | + * | This program is free software: you can redistribute it and/or modify + * | it under the terms of the GNU General Public License as published by + * | the Free Software Foundation, either version 3 of the License, or + * | any later version. + * | + * | This program is distributed in the hope that it will be useful, + * | but WITHOUT ANY WARRANTY; without even the implied warranty of + * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * | GNU General Public License for more details. + * | + * | You should have received a copy of the GNU General Public License + * | along with this program. If not, see . + * |---------------------------------------------------------------------- + */ +#include "tm_stm32f4_ds18b20.h" + +uint8_t TM_DS18B20_Start(TM_OneWire_t* OneWire, uint8_t *ROM) { + /* Check if device is DS18B20 */ + if (!TM_DS18B20_Is(ROM)) { + return 0; + } + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Start temperature conversion */ + TM_OneWire_WriteByte(OneWire, DS18B20_CMD_CONVERTTEMP); + + return 1; +} + +void TM_DS18B20_StartAll(TM_OneWire_t* OneWire) { + /* Reset pulse */ + TM_OneWire_Reset(OneWire); + /* Skip rom */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_SKIPROM); + /* Start conversion on all connected devices */ + TM_OneWire_WriteByte(OneWire, DS18B20_CMD_CONVERTTEMP); +} + +uint8_t TM_DS18B20_Read(TM_OneWire_t* OneWire, uint8_t *ROM, float *destination) { + uint16_t temperature; + uint8_t resolution; + int8_t digit, minus = 0; + float decimal; + uint8_t i = 0; + uint8_t data[9]; + uint8_t crc; + + /* Check if device is DS18B20 */ + if (!TM_DS18B20_Is(ROM)) { + return 0; + } + + /* Check if line is released, if it is, then conversion is complete */ + if (!TM_OneWire_ReadBit(OneWire)) { + /* Conversion is not finished yet */ + return 0; + } + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Read scratchpad command by onewire protocol */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); + + /* Get data */ + for (i = 0; i < 9; i++) { + /* Read byte by byte */ + data[i] = TM_OneWire_ReadByte(OneWire); + } + + /* Calculate CRC */ + crc = TM_OneWire_CRC8(data, 8); + + /* Check if CRC is ok */ + if (crc != data[8]) { + /* CRC invalid */ + return 0; + } + + /* First two bytes of scratchpad are temperature values */ + temperature = data[0] | (data[1] << 8); + + /* Reset line */ + TM_OneWire_Reset(OneWire); + + /* Check if temperature is negative */ + if (temperature & 0x8000) { + /* Two's complement, temperature is negative */ + temperature = ~temperature + 1; + minus = 1; + } + + + /* Get sensor resolution */ + resolution = ((data[4] & 0x60) >> 5) + 9; + + + /* Store temperature integer digits and decimal digits */ + digit = temperature >> 4; + digit |= ((temperature >> 8) & 0x7) << 4; + + /* Store decimal digits */ + switch (resolution) { + case 9: { + decimal = (temperature >> 3) & 0x01; + decimal *= (float)DS18B20_DECIMAL_STEPS_9BIT; + } break; + case 10: { + decimal = (temperature >> 2) & 0x03; + decimal *= (float)DS18B20_DECIMAL_STEPS_10BIT; + } break; + case 11: { + decimal = (temperature >> 1) & 0x07; + decimal *= (float)DS18B20_DECIMAL_STEPS_11BIT; + } break; + case 12: { + decimal = temperature & 0x0F; + decimal *= (float)DS18B20_DECIMAL_STEPS_12BIT; + } break; + default: { + decimal = 0xFF; + digit = 0; + } + } + + /* Check for negative part */ + decimal = digit + decimal; + if (minus) { + decimal = 0 - decimal; + } + + /* Set to pointer */ + *destination = decimal; + + /* Return 1, temperature valid */ + return 1; +} + +uint8_t TM_DS18B20_GetResolution(TM_OneWire_t* OneWire, uint8_t *ROM) { + uint8_t conf; + + if (!TM_DS18B20_Is(ROM)) { + return 0; + } + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Read scratchpad command by onewire protocol */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); + + /* Ignore first 4 bytes */ + TM_OneWire_ReadByte(OneWire); + TM_OneWire_ReadByte(OneWire); + TM_OneWire_ReadByte(OneWire); + TM_OneWire_ReadByte(OneWire); + + /* 5th byte of scratchpad is configuration register */ + conf = TM_OneWire_ReadByte(OneWire); + + /* Return 9 - 12 value according to number of bits */ + return ((conf & 0x60) >> 5) + 9; +} + +uint8_t TM_DS18B20_SetResolution(TM_OneWire_t* OneWire, uint8_t *ROM, TM_DS18B20_Resolution_t resolution) { + uint8_t th, tl, conf; + if (!TM_DS18B20_Is(ROM)) { + return 0; + } + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Read scratchpad command by onewire protocol */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); + + /* Ignore first 2 bytes */ + TM_OneWire_ReadByte(OneWire); + TM_OneWire_ReadByte(OneWire); + + th = TM_OneWire_ReadByte(OneWire); + tl = TM_OneWire_ReadByte(OneWire); + conf = TM_OneWire_ReadByte(OneWire); + + if (resolution == TM_DS18B20_Resolution_9bits) { + conf &= ~(1 << DS18B20_RESOLUTION_R1); + conf &= ~(1 << DS18B20_RESOLUTION_R0); + } else if (resolution == TM_DS18B20_Resolution_10bits) { + conf &= ~(1 << DS18B20_RESOLUTION_R1); + conf |= 1 << DS18B20_RESOLUTION_R0; + } else if (resolution == TM_DS18B20_Resolution_11bits) { + conf |= 1 << DS18B20_RESOLUTION_R1; + conf &= ~(1 << DS18B20_RESOLUTION_R0); + } else if (resolution == TM_DS18B20_Resolution_12bits) { + conf |= 1 << DS18B20_RESOLUTION_R1; + conf |= 1 << DS18B20_RESOLUTION_R0; + } + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Write scratchpad command by onewire protocol, only th, tl and conf register can be written */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_WSCRATCHPAD); + + /* Write bytes */ + TM_OneWire_WriteByte(OneWire, th); + TM_OneWire_WriteByte(OneWire, tl); + TM_OneWire_WriteByte(OneWire, conf); + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Copy scratchpad to EEPROM of DS18B20 */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_CPYSCRATCHPAD); + + return 1; +} + +uint8_t TM_DS18B20_Is(uint8_t *ROM) { + /* Checks if first byte is equal to DS18B20's family code */ + if (*ROM == DS18B20_FAMILY_CODE) { + return 1; + } + return 0; +} + +uint8_t TM_DS18B20_SetAlarmLowTemperature(TM_OneWire_t* OneWire, uint8_t *ROM, int8_t temp) { + uint8_t tl, th, conf; + if (!TM_DS18B20_Is(ROM)) { + return 0; + } + if (temp > 125) { + temp = 125; + } + if (temp < -55) { + temp = -55; + } + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Read scratchpad command by onewire protocol */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); + + /* Ignore first 2 bytes */ + TM_OneWire_ReadByte(OneWire); + TM_OneWire_ReadByte(OneWire); + + th = TM_OneWire_ReadByte(OneWire); + tl = TM_OneWire_ReadByte(OneWire); + conf = TM_OneWire_ReadByte(OneWire); + + tl = (uint8_t)temp; + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Write scratchpad command by onewire protocol, only th, tl and conf register can be written */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_WSCRATCHPAD); + + /* Write bytes */ + TM_OneWire_WriteByte(OneWire, th); + TM_OneWire_WriteByte(OneWire, tl); + TM_OneWire_WriteByte(OneWire, conf); + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Copy scratchpad to EEPROM of DS18B20 */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_CPYSCRATCHPAD); + + return 1; +} + +uint8_t TM_DS18B20_SetAlarmHighTemperature(TM_OneWire_t* OneWire, uint8_t *ROM, int8_t temp) { + uint8_t tl, th, conf; + if (!TM_DS18B20_Is(ROM)) { + return 0; + } + if (temp > 125) { + temp = 125; + } + if (temp < -55) { + temp = -55; + } + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Read scratchpad command by onewire protocol */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); + + /* Ignore first 2 bytes */ + TM_OneWire_ReadByte(OneWire); + TM_OneWire_ReadByte(OneWire); + + th = TM_OneWire_ReadByte(OneWire); + tl = TM_OneWire_ReadByte(OneWire); + conf = TM_OneWire_ReadByte(OneWire); + + th = (uint8_t)temp; + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Write scratchpad command by onewire protocol, only th, tl and conf register can be written */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_WSCRATCHPAD); + + /* Write bytes */ + TM_OneWire_WriteByte(OneWire, th); + TM_OneWire_WriteByte(OneWire, tl); + TM_OneWire_WriteByte(OneWire, conf); + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Copy scratchpad to EEPROM of DS18B20 */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_CPYSCRATCHPAD); + + return 1; +} + +uint8_t TM_DS18B20_DisableAlarmTemperature(TM_OneWire_t* OneWire, uint8_t *ROM) { + uint8_t tl, th, conf; + if (!TM_DS18B20_Is(ROM)) { + return 0; + } + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Read scratchpad command by onewire protocol */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); + + /* Ignore first 2 bytes */ + TM_OneWire_ReadByte(OneWire); + TM_OneWire_ReadByte(OneWire); + + th = TM_OneWire_ReadByte(OneWire); + tl = TM_OneWire_ReadByte(OneWire); + conf = TM_OneWire_ReadByte(OneWire); + + th = 125; + tl = (uint8_t)-55; + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Write scratchpad command by onewire protocol, only th, tl and conf register can be written */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_WSCRATCHPAD); + + /* Write bytes */ + TM_OneWire_WriteByte(OneWire, th); + TM_OneWire_WriteByte(OneWire, tl); + TM_OneWire_WriteByte(OneWire, conf); + + /* Reset line */ + TM_OneWire_Reset(OneWire); + /* Select ROM number */ + TM_OneWire_SelectWithPointer(OneWire, ROM); + /* Copy scratchpad to EEPROM of DS18B20 */ + TM_OneWire_WriteByte(OneWire, ONEWIRE_CMD_CPYSCRATCHPAD); + + return 1; +} + +uint8_t TM_DS18B20_AlarmSearch(TM_OneWire_t* OneWire) { + /* Start alarm search */ + return TM_OneWire_Search(OneWire, DS18B20_CMD_ALARMSEARCH); +} + +uint8_t TM_DS18B20_AllDone(TM_OneWire_t* OneWire) { + /* If read bit is low, then device is not finished yet with calculation temperature */ + return TM_OneWire_ReadBit(OneWire); +} + + diff --git a/src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.h b/src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.h new file mode 100644 index 0000000..337883e --- /dev/null +++ b/src/glutt-o-logique/ds18b20/tm_stm32f4_ds18b20.h @@ -0,0 +1,317 @@ +/** + * @author Tilen Majerle + * @email tilen@majerle.eu + * @website http://stm32f4-discovery.com + * @link http://stm32f4-discovery.com/2014/05/13-reading-temperature-with-dallas-ds18b20-on-stm32f429-discovery-board/ + * @version v2.0 + * @ide Keil uVision + * @license GNU GPL v3 + * @brief Library for interfacing DS18B20 temperature sensor from Dallas semiconductors. + * +@verbatim + ---------------------------------------------------------------------- + Copyright (C) Tilen Majerle, 2015 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + ---------------------------------------------------------------------- +@endverbatim + */ +/** + * Library for interfacing DS18B20 temperature sensor from Dallas semiconductors. + * + * @author Tilen Majerle + * @email tilen@majerle.eu + * @website http://stm32f4-discovery.com + * @link http://stm32f4-discovery.com/2014/05/13-reading-temperature-with-dallas-ds18b20-on-stm32f429-discovery-board/ + * @version v2.0 + * @ide Keil uVision + * @license GNU GPL v3 + * + * |---------------------------------------------------------------------- + * | Copyright (C) Tilen Majerle, 2014 + * | + * | This program is free software: you can redistribute it and/or modify + * | it under the terms of the GNU General Public License as published by + * | the Free Software Foundation, either version 3 of the License, or + * | any later version. + * | + * | This program is distributed in the hope that it will be useful, + * | but WITHOUT ANY WARRANTY; without even the implied warranty of + * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * | GNU General Public License for more details. + * | + * | You should have received a copy of the GNU General Public License + * | along with this program. If not, see . + * |---------------------------------------------------------------------- + * + * Version 2.0 + * - January 04, 2015 + * - New system, supporting OneWire library 2.0 + * + * Version 1.1 + * - December 06, 2014 + * - Now CRC is calculated and checked if data are valid + * - New version of OneWire library is required, download already available on stm32f4-discovery.com + * + * With this you can read temperature, set and get temperature resolution from 9 to 12 bits + * and check if device is DS18B20 + * + * Pin for STM32F4xx is the same as set with TM ONEWIRE library. + */ +#ifndef TM_DS18B20_H +#define TM_DS18B20_H 200 + +/** + * @addtogroup TM_STM32F4xx_Libraries + * @{ + */ + +/** + * @defgroup TM_DS12820 + * @brief Library for interfacing DS18B20 temperature sensor from Dallas semiconductors - http://stm32f4-discovery.com/2014/05/13-reading-temperature-with-dallas-ds18b20-on-stm32f429-discovery-board/ + * @{ + * + * With this you can read temperature, set and get temperature resolution from 9 to 12 bits and check if device is DS18B20. + * + * Pin for STM32F4xx is the same as set with TM ONEWIRE library. + * + * \par Changelog + * +@verbatim + Version 2.0 + - January 04, 2015 + - New system, supporting OneWire library 2.0 + + Version 1.1 + - December 06, 2014 + - Now CRC is calculated and checked if data are valid + - New version of OneWire library is required, download already available on stm32f4-discovery.com + + Version 1.0 + - First release +@endverbatim + * + * \par Dependencies + * +@verbatim + - STM32F4xx + - TM ONEWIRE + - TM GPIO +@endverbatim + */ + +#include "stm32f4xx.h" +#include "tm_stm32f4_onewire.h" + +/* OneWire version check */ +#if TM_ONEWIRE_H < 200 +#error "Please update TM ONEWIRE LIB, minimum required version is 2.0.0. Download available on stm32f4-discovery.com website" +#endif + +/** + * @defgroup TM_DS18B20_Macros + * @brief Library defines + * @{ + */ + +/* Every onewire chip has different ROM code, but all the same chips has same family code */ +/* in case of DS18B20 this is 0x28 and this is first byte of ROM address */ +#define DS18B20_FAMILY_CODE 0x28 +#define DS18B20_CMD_ALARMSEARCH 0xEC + +/* DS18B20 read temperature command */ +#define DS18B20_CMD_CONVERTTEMP 0x44 /* Convert temperature */ +#define DS18B20_DECIMAL_STEPS_12BIT 0.0625 +#define DS18B20_DECIMAL_STEPS_11BIT 0.125 +#define DS18B20_DECIMAL_STEPS_10BIT 0.25 +#define DS18B20_DECIMAL_STEPS_9BIT 0.5 + +/* Bits locations for resolution */ +#define DS18B20_RESOLUTION_R1 6 +#define DS18B20_RESOLUTION_R0 5 + +/* CRC enabled */ +#ifdef DS18B20_USE_CRC +#define DS18B20_DATA_LEN 9 +#else +#define DS18B20_DATA_LEN 2 +#endif + +/** + * @} + */ + +/** + * @defgroup TM_DS18B20_Typedefs + * @brief Library Typedefs + * @{ + */ + +/** + * @brief DS18B0 Resolutions available + */ +typedef enum { + TM_DS18B20_Resolution_9bits = 9, /*!< DS18B20 9 bits resolution */ + TM_DS18B20_Resolution_10bits = 10, /*!< DS18B20 10 bits resolution */ + TM_DS18B20_Resolution_11bits = 11, /*!< DS18B20 11 bits resolution */ + TM_DS18B20_Resolution_12bits = 12 /*!< DS18B20 12 bits resolution */ +} TM_DS18B20_Resolution_t; + +/** + * @} + */ + +/** + * @defgroup TM_DS18B20_Functions + * @brief Library Functions + * @{ + */ + +/** + * @brief Starts temperature conversion for specific DS18B20 on specific onewire channel + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. + * Entire ROM address is 8-bytes long + * @retval 1 if device is DS18B20 or 0 if not + */ +uint8_t TM_DS18B20_Start(TM_OneWire_t* OneWireStruct, uint8_t* ROM); + +/** + * @brief Starts temperature conversion for all DS18B20 devices on specific onewire channel + * @note This mode will skip ROM addressing + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @retval None + */ +void TM_DS18B20_StartAll(TM_OneWire_t* OneWireStruct); + +/** + * @brief Reads temperature from DS18B20 + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. + * Entire ROM address is 8-bytes long + * @param *destination: Pointer to float variable to store temperature + * @retval Temperature status: + * - 0: Device is not DS18B20 or conversion is not done yet or CRC failed + * - > 0: Temperature is read OK + */ +uint8_t TM_DS18B20_Read(TM_OneWire_t* OneWireStruct, uint8_t* ROM, float* destination); + +/** + * @brief Gets resolution for temperature conversion from DS18B20 device + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. + * Entire ROM address is 8-bytes long + * @retval Resolution: + * - 0: Device is not DS18B20 + * - 9 - 12: Resolution of DS18B20 + */ +uint8_t TM_DS18B20_GetResolution(TM_OneWire_t* OneWireStruct, uint8_t* ROM); + +/** + * @brief Sets resolution for specific DS18B20 device + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. + * Entire ROM address is 8-bytes long + * @param resolution: Resolution for DS18B20 device. This parameter can be a value of @ref TM_DS18B20_Resolution_t enumeration. + * @retval Success status: + * - 0: Device is not DS18B20 + * - > 0: Resolution set OK + */ +uint8_t TM_DS18B20_SetResolution(TM_OneWire_t* OneWireStruct, uint8_t* ROM, TM_DS18B20_Resolution_t resolution); + +/** + * @brief Checks if device with specific ROM number is DS18B20 + * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. + * Entire ROM address is 8-bytes long + * @retval Device status + * - 0: Device is not DS18B20 + * - > 0: Device is DS18B20 + */ +uint8_t TM_DS18B20_Is(uint8_t* ROM); + +/** + * @brief Sets high alarm temperature to specific DS18B20 sensor + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. + * Entire ROM address is 8-bytes long + * @param temp: integer value for temperature between -55 to 125 degrees + * @retval Success status: + * - 0: Device is not DS18B20 + * - > 0: High alarm set OK + */ +uint8_t TM_DS18B20_SetAlarmHighTemperature(TM_OneWire_t* OneWireStruct, uint8_t* ROM, int8_t temp); + +/** + * @brief Sets low alarm temperature to specific DS18B20 sensor + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. + * Entire ROM address is 8-bytes long + * @param temp: integer value for temperature between -55 to 125 degrees + * @retval Success status: + * - 0: Device is not DS18B20 + * - > 0: Low alarm set OK + */ +uint8_t TM_DS18B20_SetAlarmLowTemperature(TM_OneWire_t* OneWireStruct, uint8_t* ROM, int8_t temp); + +/** + * @brief Disables alarm temperature for specific DS18B20 sensor + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @param *ROM: Pointer to first byte of ROM address for desired DS12B80 device. + * Entire ROM address is 8-bytes long + * @retval Success status: + * - 0: Device is not DS18B20 + * - > 0: Alarm disabled OK + */ +uint8_t TM_DS18B20_DisableAlarmTemperature(TM_OneWire_t* OneWireStruct, uint8_t* ROM); + +/** + * @brief Searches for devices with alarm flag set + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @retval Alarm search status + * - 0: No device found with alarm flag set + * - > 0: Device is found with alarm flag + * @note To get all devices on one onewire channel with alarm flag set, you can do this: +@verbatim +while (TM_DS18B20_AlarmSearch(&OneWireStruct)) { + //Read device ID here + //Print to user device by device +} +@endverbatim + * @retval 1 if any device has flag, otherwise 0 + */ +uint8_t TM_DS18B20_AlarmSearch(TM_OneWire_t* OneWireStruct); + +/** + * @brief Checks if all DS18B20 sensors are done with temperature conversion + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working structure (OneWire channel) + * @retval Conversion status + * - 0: Not all devices are done + * - > 0: All devices are done with conversion + */ +uint8_t TM_DS18B20_AllDone(TM_OneWire_t* OneWireStruct); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif + diff --git a/src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.c b/src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.c new file mode 100644 index 0000000..44ec8db --- /dev/null +++ b/src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.c @@ -0,0 +1,414 @@ +/** + * |---------------------------------------------------------------------- + * | Copyright (C) Tilen Majerle, 2014 + * | + * | This program is free software: you can redistribute it and/or modify + * | it under the terms of the GNU General Public License as published by + * | the Free Software Foundation, either version 3 of the License, or + * | any later version. + * | + * | This program is distributed in the hope that it will be useful, + * | but WITHOUT ANY WARRANTY; without even the implied warranty of + * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * | GNU General Public License for more details. + * | + * | You should have received a copy of the GNU General Public License + * | along with this program. If not, see . + * |---------------------------------------------------------------------- + */ +#include "tm_stm32f4_onewire.h" + +void delay_us(uint32_t); + +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); +} + +static void +TM_GPIO_SetPinAsOutput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ +#if 0 + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + 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 + GPIO_ResetBits(GPIOx, GPIO_Pin); +} + +static int +TM_GPIO_GetInputPinValue(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + return GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) ? 1 : 0; +} + +static void +ONEWIRE_DELAY(uint32_t micros) +{ + delay_us(micros); +} + +void TM_OneWire_Init(TM_OneWire_t* OneWireStruct, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { + ONEWIRE_INPUT(OneWireStruct); + /* Save settings */ + OneWireStruct->GPIOx = GPIOx; + OneWireStruct->GPIO_Pin = GPIO_Pin; +} + +uint8_t TM_OneWire_Reset(TM_OneWire_t* OneWireStruct) { + uint8_t i; + + /* Line low, and wait 480us */ + ONEWIRE_LOW(OneWireStruct); + ONEWIRE_OUTPUT(OneWireStruct); + ONEWIRE_DELAY(480); + + /* Release line and wait for 70us */ + ONEWIRE_INPUT(OneWireStruct); + ONEWIRE_DELAY(70); + + /* Check bit value */ + i = TM_GPIO_GetInputPinValue(OneWireStruct->GPIOx, OneWireStruct->GPIO_Pin); + + /* Delay for 410 us */ + ONEWIRE_DELAY(410); + + /* Return value of presence pulse, 0 = OK, 1 = ERROR */ + return i; +} + +void TM_OneWire_WriteBit(TM_OneWire_t* OneWireStruct, uint8_t bit) { + if (bit) { + /* Set line low */ + ONEWIRE_LOW(OneWireStruct); + ONEWIRE_OUTPUT(OneWireStruct); + ONEWIRE_DELAY(10); + + /* Bit high */ + ONEWIRE_INPUT(OneWireStruct); + + /* Wait for 55 us and release the line */ + ONEWIRE_DELAY(55); + ONEWIRE_INPUT(OneWireStruct); + } else { + /* Set line low */ + ONEWIRE_LOW(OneWireStruct); + ONEWIRE_OUTPUT(OneWireStruct); + ONEWIRE_DELAY(65); + + /* Bit high */ + ONEWIRE_INPUT(OneWireStruct); + + /* Wait for 5 us and release the line */ + ONEWIRE_DELAY(5); + ONEWIRE_INPUT(OneWireStruct); + } + +} + +uint8_t TM_OneWire_ReadBit(TM_OneWire_t* OneWireStruct) { + uint8_t bit = 0; + + /* Line low */ + ONEWIRE_LOW(OneWireStruct); + ONEWIRE_OUTPUT(OneWireStruct); + ONEWIRE_DELAY(3); + + /* Release line */ + ONEWIRE_INPUT(OneWireStruct); + ONEWIRE_DELAY(10); + + /* Read line value */ + if (TM_GPIO_GetInputPinValue(OneWireStruct->GPIOx, OneWireStruct->GPIO_Pin)) { + /* Bit is HIGH */ + bit = 1; + } + + /* Wait 50us to complete 60us period */ + ONEWIRE_DELAY(50); + + /* Return bit value */ + return bit; +} + +void TM_OneWire_WriteByte(TM_OneWire_t* OneWireStruct, uint8_t byte) { + uint8_t i = 8; + /* Write 8 bits */ + while (i--) { + /* LSB bit is first */ + TM_OneWire_WriteBit(OneWireStruct, byte & 0x01); + byte >>= 1; + } +} + +uint8_t TM_OneWire_ReadByte(TM_OneWire_t* OneWireStruct) { + uint8_t i = 8, byte = 0; + while (i--) { + byte >>= 1; + byte |= (TM_OneWire_ReadBit(OneWireStruct) << 7); + } + + return byte; +} + +uint8_t TM_OneWire_First(TM_OneWire_t* OneWireStruct) { + /* Reset search values */ + TM_OneWire_ResetSearch(OneWireStruct); + + /* Start with searching */ + return TM_OneWire_Search(OneWireStruct, ONEWIRE_CMD_SEARCHROM); +} + +uint8_t TM_OneWire_Next(TM_OneWire_t* OneWireStruct) { + /* Leave the search state alone */ + return TM_OneWire_Search(OneWireStruct, ONEWIRE_CMD_SEARCHROM); +} + +void TM_OneWire_ResetSearch(TM_OneWire_t* OneWireStruct) { + /* Reset the search state */ + OneWireStruct->LastDiscrepancy = 0; + OneWireStruct->LastDeviceFlag = 0; + OneWireStruct->LastFamilyDiscrepancy = 0; +} + +uint8_t TM_OneWire_Search(TM_OneWire_t* OneWireStruct, uint8_t command) { + uint8_t id_bit_number; + uint8_t last_zero, rom_byte_number, search_result; + uint8_t id_bit, cmp_id_bit; + uint8_t rom_byte_mask, search_direction; + + /* Initialize for search */ + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + + // if the last call was not the last one + if (!OneWireStruct->LastDeviceFlag) { + // 1-Wire reset + if (TM_OneWire_Reset(OneWireStruct)) { + /* Reset the search */ + OneWireStruct->LastDiscrepancy = 0; + OneWireStruct->LastDeviceFlag = 0; + OneWireStruct->LastFamilyDiscrepancy = 0; + return 0; + } + + // issue the search command + TM_OneWire_WriteByte(OneWireStruct, command); + + // loop to do the search + do { + // read a bit and its complement + id_bit = TM_OneWire_ReadBit(OneWireStruct); + cmp_id_bit = TM_OneWire_ReadBit(OneWireStruct); + + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) { + break; + } else { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) { + search_direction = id_bit; // bit write value for search + } else { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < OneWireStruct->LastDiscrepancy) { + search_direction = ((OneWireStruct->ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + } else { + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == OneWireStruct->LastDiscrepancy); + } + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) { + last_zero = id_bit_number; + + // check for Last discrepancy in family + if (last_zero < 9) { + OneWireStruct->LastFamilyDiscrepancy = last_zero; + } + } + } + + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == 1) { + OneWireStruct->ROM_NO[rom_byte_number] |= rom_byte_mask; + } else { + OneWireStruct->ROM_NO[rom_byte_number] &= ~rom_byte_mask; + } + + // serial number search direction write bit + TM_OneWire_WriteBit(OneWireStruct, search_direction); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) { + //docrc8(ROM_NO[rom_byte_number]); // accumulate the CRC + rom_byte_number++; + rom_byte_mask = 1; + } + } + } while (rom_byte_number < 8); // loop until through all ROM bytes 0-7 + + // if the search was successful then + if (!(id_bit_number < 65)) { + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + OneWireStruct->LastDiscrepancy = last_zero; + + // check for last device + if (OneWireStruct->LastDiscrepancy == 0) { + OneWireStruct->LastDeviceFlag = 1; + } + + search_result = 1; + } + } + + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || !OneWireStruct->ROM_NO[0]) { + OneWireStruct->LastDiscrepancy = 0; + OneWireStruct->LastDeviceFlag = 0; + OneWireStruct->LastFamilyDiscrepancy = 0; + search_result = 0; + } + + return search_result; +} + +int TM_OneWire_Verify(TM_OneWire_t* OneWireStruct) { + unsigned char rom_backup[8]; + int i,rslt,ld_backup,ldf_backup,lfd_backup; + + // keep a backup copy of the current state + for (i = 0; i < 8; i++) + rom_backup[i] = OneWireStruct->ROM_NO[i]; + ld_backup = OneWireStruct->LastDiscrepancy; + ldf_backup = OneWireStruct->LastDeviceFlag; + lfd_backup = OneWireStruct->LastFamilyDiscrepancy; + + // set search to find the same device + OneWireStruct->LastDiscrepancy = 64; + OneWireStruct->LastDeviceFlag = 0; + + if (TM_OneWire_Search(OneWireStruct, ONEWIRE_CMD_SEARCHROM)) { + // check if same device found + rslt = 1; + for (i = 0; i < 8; i++) { + if (rom_backup[i] != OneWireStruct->ROM_NO[i]) { + rslt = 1; + break; + } + } + } else { + rslt = 0; + } + + // restore the search state + for (i = 0; i < 8; i++) { + OneWireStruct->ROM_NO[i] = rom_backup[i]; + } + OneWireStruct->LastDiscrepancy = ld_backup; + OneWireStruct->LastDeviceFlag = ldf_backup; + OneWireStruct->LastFamilyDiscrepancy = lfd_backup; + + // return the result of the verify + return rslt; +} + +void TM_OneWire_TargetSetup(TM_OneWire_t* OneWireStruct, uint8_t family_code) { + uint8_t i; + + // set the search state to find SearchFamily type devices + OneWireStruct->ROM_NO[0] = family_code; + for (i = 1; i < 8; i++) { + OneWireStruct->ROM_NO[i] = 0; + } + + OneWireStruct->LastDiscrepancy = 64; + OneWireStruct->LastFamilyDiscrepancy = 0; + OneWireStruct->LastDeviceFlag = 0; +} + +void TM_OneWire_FamilySkipSetup(TM_OneWire_t* OneWireStruct) { + // set the Last discrepancy to last family discrepancy + OneWireStruct->LastDiscrepancy = OneWireStruct->LastFamilyDiscrepancy; + OneWireStruct->LastFamilyDiscrepancy = 0; + + // check for end of list + if (OneWireStruct->LastDiscrepancy == 0) { + OneWireStruct->LastDeviceFlag = 1; + } +} + +uint8_t TM_OneWire_GetROM(TM_OneWire_t* OneWireStruct, uint8_t index) { + return OneWireStruct->ROM_NO[index]; +} + +void TM_OneWire_Select(TM_OneWire_t* OneWireStruct, uint8_t* addr) { + uint8_t i; + TM_OneWire_WriteByte(OneWireStruct, ONEWIRE_CMD_MATCHROM); + + for (i = 0; i < 8; i++) { + TM_OneWire_WriteByte(OneWireStruct, *(addr + i)); + } +} + +void TM_OneWire_SelectWithPointer(TM_OneWire_t* OneWireStruct, uint8_t *ROM) { + uint8_t i; + TM_OneWire_WriteByte(OneWireStruct, ONEWIRE_CMD_MATCHROM); + + for (i = 0; i < 8; i++) { + TM_OneWire_WriteByte(OneWireStruct, *(ROM + i)); + } +} + +void TM_OneWire_GetFullROM(TM_OneWire_t* OneWireStruct, uint8_t *firstIndex) { + uint8_t i; + for (i = 0; i < 8; i++) { + *(firstIndex + i) = OneWireStruct->ROM_NO[i]; + } +} + +uint8_t TM_OneWire_CRC8(uint8_t *addr, uint8_t len) { + uint8_t crc = 0, inbyte, i, mix; + + while (len--) { + inbyte = *addr++; + for (i = 8; i; i--) { + mix = (crc ^ inbyte) & 0x01; + crc >>= 1; + if (mix) { + crc ^= 0x8C; + } + inbyte >>= 1; + } + } + + /* Return calculated CRC */ + return crc; +} diff --git a/src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.h b/src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.h new file mode 100644 index 0000000..9b14109 --- /dev/null +++ b/src/glutt-o-logique/ds18b20/tm_stm32f4_onewire.h @@ -0,0 +1,300 @@ +/** + * @author Tilen Majerle + * @email tilen@majerle.eu + * @website http://stm32f4-discovery.com + * @link http://stm32f4-discovery.com/2014/05/library-12-onewire-library-for-stm43f4xx/ + * @version v2.1 + * @ide Keil uVision + * @license GNU GPL v3 + * @brief Onewire library for STM32F4 devices + * +@verbatim + ---------------------------------------------------------------------- + Copyright (C) Tilen Majerle, 2015 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + ---------------------------------------------------------------------- +@endverbatim + */ +#ifndef TM_ONEWIRE_H +#define TM_ONEWIRE_H 210 + +/* C++ detection */ +#ifdef __cplusplus +extern C { +#endif + +/** + * @addtogroup TM_STM32F4xx_Libraries + * @{ + */ + +/** + * @defgroup TM_ONEWIRE + * @brief Onewire library for STM32F4 devices - http://stm32f4-discovery.com/2014/05/library-12-onewire-library-for-stm43f4xx/ + * @{ + * + * As of version 2.0 you can now use more than just one one-wire "port" on STM32F4. This allows you to group devices to separate ports. + * + * Because if you have a loot devices on one port, if one device fail, everything is failed. You can prevent this by use more than just one port. + * + * To set your port and pin for OneWire protocol, you can do this when calling @ref TM_OneWire_Init function. + * + * \par Changelog + * +@verbatim + Version 2.1 + - March 10, 2015 + - Added support for new GPIO library + + Version 2.0 + - January 04, 2015 + - New OneWire system + - With support for multiple OneWire ports to separate group of devices + + Version 1.1 + - December 06, 2014 + - Added 8-bit CRC calculation for 1-Wire devices, algorithm from Dallas + + Version 1.0 + - First release +@endverbatim + * + * \par Dependencies + * +@verbatim + - STM32F4xx + - STM32F4xx RCC + - STM32F4xx GPIO + - TM GPIO +@endverbatim + */ +#include "stm32f4xx.h" +#include "stm32f4xx_rcc.h" +#include "stm32f4xx_gpio.h" + +/** + * @defgroup TM_ONEWIRE_Macros + * @brief Library defines + * @{ + */ + +/* Pin settings */ + +#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) + +/* OneWire commands */ +#define ONEWIRE_CMD_RSCRATCHPAD 0xBE +#define ONEWIRE_CMD_WSCRATCHPAD 0x4E +#define ONEWIRE_CMD_CPYSCRATCHPAD 0x48 +#define ONEWIRE_CMD_RECEEPROM 0xB8 +#define ONEWIRE_CMD_RPWRSUPPLY 0xB4 +#define ONEWIRE_CMD_SEARCHROM 0xF0 +#define ONEWIRE_CMD_READROM 0x33 +#define ONEWIRE_CMD_MATCHROM 0x55 +#define ONEWIRE_CMD_SKIPROM 0xCC + +/** + * @} + */ + +/** + * @defgroup TM_ONEWIRE_Typedefs + * @brief Library Typedefs + * @{ + */ + +/** + * @brief OneWire working struct + * @note Except ROM_NO member, everything is fully private and should not be touched by user + */ +typedef struct { + GPIO_TypeDef* GPIOx; /*!< GPIOx port to be used for I/O functions */ + uint16_t GPIO_Pin; /*!< GPIO Pin to be used for I/O functions */ + uint8_t LastDiscrepancy; /*!< Search private */ + uint8_t LastFamilyDiscrepancy; /*!< Search private */ + uint8_t LastDeviceFlag; /*!< Search private */ + uint8_t ROM_NO[8]; /*!< 8-bytes address of last search device */ +} TM_OneWire_t; + +/** + * @} + */ + +/** + * @defgroup TM_ONEWIRE_Functions + * @brief Library Functions + * @{ + */ + +/** + * @brief Initializes OneWire bus + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t empty working onewire structure + * @param *Pointer to GPIO port used for onewire channel + * @param GPIO_Pin: GPIO Pin on specific GPIOx to be used for onewire channel + * @retval None + */ +void TM_OneWire_Init(TM_OneWire_t* OneWireStruct, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + +/** + * @brief Resets OneWire bus + * + * @note Sends reset command for OneWire + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure + * @retval None + */ +uint8_t TM_OneWire_Reset(TM_OneWire_t* OneWireStruct); + +/** + * @brief Reads byte from one wire bus + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure + * @retval Byte from read operation + */ +uint8_t TM_OneWire_ReadByte(TM_OneWire_t* OneWireStruct); + +/** + * @brief Writes byte to bus + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure + * @param byte: 8-bit value to write over OneWire protocol + * @retval None + */ +void TM_OneWire_WriteByte(TM_OneWire_t* OneWireStruct, uint8_t byte); + +/** + * @brief Writes single bit to onewire bus + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure + * @param bit: Bit value to send, 1 or 0 + * @retval None + */ +void TM_OneWire_WriteBit(TM_OneWire_t* OneWireStruct, uint8_t bit); + +/** + * @brief Reads single bit from one wire bus + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure + * @retval Bit value: + * - 0: Bit is low (zero) + * - > 0: Bit is high (one) + */ +uint8_t TM_OneWire_ReadBit(TM_OneWire_t* OneWireStruct); + +/** + * @brief Searches for OneWire devices on specific Onewire port + * @note Not meant for public use. Use @ref TM_OneWire_First and @ref TM_OneWire_Next for this. + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire structure where to search + * @param Device status: + * - 0: No devices detected + * - > 0: Device detected + */ +uint8_t TM_OneWire_Search(TM_OneWire_t* OneWireStruct, uint8_t command); + +/** + * @brief Resets search states + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire where to reset search values + * @retval None + */ +void TM_OneWire_ResetSearch(TM_OneWire_t* OneWireStruct); + +/** + * @brief Starts search, reset states first + * @note When you want to search for ALL devices on one onewire port, you should first use this function. +@verbatim +/...Initialization before +status = TM_OneWire_First(&OneWireStruct); +while (status) { + //Save ROM number from device + TM_OneWire_GetFullROM(ROM_Array_Pointer); + //Check for new device + status = TM_OneWire_Next(&OneWireStruct); +} +@endverbatim + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire where to reset search values + * @param Device status: + * - 0: No devices detected + * - > 0: Device detected + */ +uint8_t TM_OneWire_First(TM_OneWire_t* OneWireStruct); + +/** + * @brief Reads next device + * @note Use @ref TM_OneWire_First to start searching + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire + * @param Device status: + * - 0: No devices detected any more + * - > 0: New device detected + */ +uint8_t TM_OneWire_Next(TM_OneWire_t* OneWireStruct); + +/** + * @brief Gets ROM number from device from search + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire + * @param index: Because each device has 8-bytes long ROm address, you have to call this 8 times, to get ROM bytes from 0 to 7 + * @reetval ROM byte for index (0 to 7) at current found device + */ +uint8_t TM_OneWire_GetROM(TM_OneWire_t* OneWireStruct, uint8_t index); + +/** + * @brief Gets all 8 bytes ROM value from device from search + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire + * @param *firstIndex: Pointer to first location for first byte, other bytes are automatically incremented + * @retval None + */ +void TM_OneWire_GetFullROM(TM_OneWire_t* OneWireStruct, uint8_t *firstIndex); + +/** + * @brief Selects specific slave on bus + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire + * @param *addr: Pointer to first location of 8-bytes long ROM address + * @retval None + */ +void TM_OneWire_Select(TM_OneWire_t* OneWireStruct, uint8_t* addr); + +/** + * @brief Selects specific slave on bus with pointer address + * @param *OneWireStruct: Pointer to @ref TM_OneWire_t working onewire + * @param *ROM: Pointer to first byte of ROM address + * @retval None + */ +void TM_OneWire_SelectWithPointer(TM_OneWire_t* OneWireStruct, uint8_t* ROM); + +/** + * @brief Calculates 8-bit CRC for 1-wire devices + * @param *addr: Pointer to 8-bit array of data to calculate CRC + * @param len: Number of bytes to check + * + * @retval Calculated CRC from input data + */ +uint8_t TM_OneWire_CRC8(uint8_t* addr, uint8_t len); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/* C++ detection */ +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/glutt-o-logique/fsm.c b/src/glutt-o-logique/fsm.c new file mode 100644 index 0000000..99413ba --- /dev/null +++ b/src/glutt-o-logique/fsm.c @@ -0,0 +1,8 @@ +#include "../../../common/src/Core/fsm.c" + + +void fsm_state_switched(char * new_state) { + usart_debug_puts("FSM: "); + usart_debug_puts(new_state); + usart_debug_puts("\r\n"); +} diff --git a/src/glutt-o-logique/gps.c b/src/glutt-o-logique/gps.c new file mode 100644 index 0000000..10afe88 --- /dev/null +++ b/src/glutt-o-logique/gps.c @@ -0,0 +1,4 @@ +#include "stm32f4xx_conf.h" +#include "stm32f4xx.h" + +#include "../../../common/src/GPS/gps.c" diff --git a/src/glutt-o-logique/i2c.c b/src/glutt-o-logique/i2c.c new file mode 100644 index 0000000..750f5de --- /dev/null +++ b/src/glutt-o-logique/i2c.c @@ -0,0 +1,350 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Matthias P. Braendli + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + +#include "GPIO/i2c.h" +#include "Core/common.h" + +#include "stm32f4xx_conf.h" +#include "stm32f4xx_i2c.h" +#include "stm32f4xx.h" +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "task.h" +#include "semphr.h" +#include "GPIO/usart.h" + +/* I2C 1 on PB9 and PB6 + * See pio.txt for PIO allocation details */ +const uint16_t GPIOB_PIN_SDA = GPIO_Pin_9; +const uint16_t GPIOB_PIN_SCL = GPIO_Pin_6; + + +static int i2c_init_done = 0; +static int i2c_error = 0; + +static I2C_TypeDef* const I2Cx = I2C1; + +static SemaphoreHandle_t i2c_semaphore; + +static void i2c_device_init(void); + +/* According to I2C spec UM10204: + * 3.1.16 Bus clear + * In the unlikely event where the clock (SCL) is stuck LOW, the preferential + * procedure is to reset the bus using the HW reset signal if your I2C devices + * have HW reset inputs. If the I2C devices do not have HW reset inputs, cycle + * power to the devices to activate the mandatory internal Power-On Reset (POR) + * circuit. + * + * If the data line (SDA) is stuck LOW, the master should send nine clock + * pulses. The device that held the bus LOW should release it sometime within + * those nine clocks. If not, then use the HW reset or cycle power to clear the + * bus. + */ +static void i2c_recover_from_lockup(void) +{ + usart_debug_puts("ERROR: I2C lockup\r\n"); + + I2C_SoftwareResetCmd(I2Cx, ENABLE); + + // Configure I2C SCL and SDA pins. + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIOB_PIN_SCL | GPIOB_PIN_SDA; + 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(GPIOB, &GPIO_InitStructure); + + const TickType_t delay = 5 / portTICK_PERIOD_MS; + + GPIO_SetBits(GPIOB, GPIOB_PIN_SDA | GPIOB_PIN_SCL); + vTaskDelay(delay); + + for (int i = 0; i < 10; i++) { + GPIO_ResetBits(GPIOB, GPIOB_PIN_SCL); + vTaskDelay(delay); + GPIO_SetBits(GPIOB, GPIOB_PIN_SCL); + vTaskDelay(delay); + } + + I2C_SoftwareResetCmd(I2Cx, DISABLE); + + i2c_device_init(); +} + +static void i2c_device_init(void) +{ + // Configure I2C SCL and SDA pins. + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIOB_PIN_SCL | GPIOB_PIN_SDA; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1); + + // Reset I2C. + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); + + // configure I2C1 + I2C_InitTypeDef I2C_InitStruct; + I2C_InitStruct.I2C_ClockSpeed = 100000; //Hz + I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; + I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle + I2C_InitStruct.I2C_OwnAddress1 = 0x00; // not relevant in master mode + + // disable acknowledge when reading (can be changed later on) + I2C_InitStruct.I2C_Ack = I2C_Ack_Disable; + + I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_Init(I2C1, &I2C_InitStruct); + + // enable I2C1 + I2C_Cmd(I2C1, ENABLE); +} + +void i2c_init() +{ + if (i2c_init_done == 1) { + return; + } + + i2c_semaphore = xSemaphoreCreateBinary(); + + if ( i2c_semaphore == NULL ) { + trigger_fault(FAULT_SOURCE_I2C); + } + else { + xSemaphoreGive(i2c_semaphore); + } + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); + + i2c_device_init(); + i2c_init_done = 1; +} + +static int i2c_check_busy_flag(void) +{ + const TickType_t i2c_timeout = 1000ul / portTICK_PERIOD_MS; + const TickType_t time_start = xTaskGetTickCount(); + + while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)) { + const TickType_t time_now = xTaskGetTickCount(); + + if (time_now - time_start > i2c_timeout) { + i2c_error = 1; + return 0; + } + } + + return 1; +} + +static int i2c_check_event(uint32_t event) +{ + const TickType_t i2c_timeout = 1000ul / portTICK_PERIOD_MS; + const TickType_t time_start = xTaskGetTickCount(); + + while (!I2C_CheckEvent(I2Cx, event)) { + const TickType_t time_now = xTaskGetTickCount(); + + if (time_now - time_start > i2c_timeout) { + i2c_error = 1; + return 0; + } + } + + return 1; +} + +static int i2c_start(uint8_t device, uint8_t direction) +{ + I2C_GenerateSTART(I2Cx, ENABLE); + + // wait for bus free + if (!i2c_check_event(I2C_EVENT_MASTER_MODE_SELECT)) { + I2C_GenerateSTART(I2Cx, DISABLE); + return 0; + } + + I2C_Send7bitAddress(I2Cx, device << 1, direction); + + /* wait for I2C1 EV6, check if + * either Slave has acknowledged Master transmitter or + * Master receiver mode, depending on the transmission + * direction + */ + uint32_t event = 0; + if (direction == I2C_Direction_Transmitter) { + event = I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED; + } + else if (direction == I2C_Direction_Receiver) { + event = I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED; + } + else { + trigger_fault(FAULT_SOURCE_I2C); + } + + if (!i2c_check_event(event)) { + return 0; + } + + return 1; +} + +static int i2c_send(uint8_t data) +{ + I2C_SendData(I2Cx, data); + + // wait for I2C1 EV8_2 --> byte has been transmitted + return i2c_check_event(I2C_EVENT_MASTER_BYTE_TRANSMITTED); +} + +int i2c_write(uint8_t device, const uint8_t *txbuf, int len) +{ + if (i2c_init_done == 0) { + trigger_fault(FAULT_SOURCE_I2C); + } + + int success = i2c_check_busy_flag(); + + if (success) { + success = i2c_start(device, I2C_Direction_Transmitter); + } + + if (success) { + for (int i = 0; i < len; i++) { + success = i2c_send(txbuf[i]); + if (!success) { + break; + } + } + + I2C_GenerateSTOP(I2Cx, ENABLE); + success = i2c_check_event(I2C_EVENT_MASTER_BYTE_TRANSMITTED); + } + + return success; +} + +static int i2c_read_nobuscheck(uint8_t device, uint8_t *rxbuf, int len) +{ + if (i2c_init_done == 0) { + trigger_fault(FAULT_SOURCE_I2C); + } + + if (i2c_start(device, I2C_Direction_Receiver)) { + for (int i = 0; i < len; i++) { + if (i == len-1) { + I2C_AcknowledgeConfig(I2Cx, DISABLE); + } + else { + I2C_AcknowledgeConfig(I2Cx, ENABLE); + } + + // wait until one byte has been received, possibly timout + if (!i2c_check_event(I2C_EVENT_MASTER_BYTE_RECEIVED)) { + I2C_GenerateSTOP(I2Cx, ENABLE); + return 0; + } + + if (i == len-1) { + I2C_GenerateSTOP(I2Cx, ENABLE); + } + + rxbuf[i] = I2C_ReceiveData(I2Cx); + } + return len; + } + + return 0; +} + +int i2c_read(uint8_t device, uint8_t *rxbuf, int len) +{ + int success = i2c_check_busy_flag(); + + if (success) { + success = i2c_read_nobuscheck(device, rxbuf, len); + } + + return success; +} + +int i2c_read_from(uint8_t device, uint8_t address, uint8_t *rxbuf, int len) +{ + if (i2c_init_done == 0) { + trigger_fault(FAULT_SOURCE_I2C); + } + + int success = i2c_check_busy_flag(); + + if (success) { + success = i2c_start(device, I2C_Direction_Transmitter); + } + + if (success) { + success = i2c_send(address); + } + // Don't do a STOP + + if (success) { + success = i2c_read_nobuscheck(device, rxbuf, len); + } + + return success; +} + + + +void i2c_transaction_start() +{ + if (i2c_init_done == 0) { + trigger_fault(FAULT_SOURCE_I2C); + } + xSemaphoreTake(i2c_semaphore, portMAX_DELAY); +} + +void i2c_transaction_end() +{ + if (i2c_init_done == 0) { + trigger_fault(FAULT_SOURCE_I2C); + } + + if ( i2c_error ) { + i2c_recover_from_lockup(); + + i2c_error = 0; + } + + xSemaphoreGive(i2c_semaphore); +} + diff --git a/src/glutt-o-logique/leds.c b/src/glutt-o-logique/leds.c new file mode 100644 index 0000000..88b46bf --- /dev/null +++ b/src/glutt-o-logique/leds.c @@ -0,0 +1,42 @@ +#include "../../../common/src/GPIO/leds.c" + +#include "stm32f4xx_conf.h" + +#include "leds.h" + +void leds_turn_on(int l) { + + switch (l) { + case LED_GREEN: + GPIO_SetBits(GPIOD, GPIOD_BOARD_LED_GREEN); + break; + case LED_ORANGE: + GPIO_SetBits(GPIOD, GPIOD_BOARD_LED_ORANGE); + break; + case LED_RED: + GPIO_SetBits(GPIOD, GPIOD_BOARD_LED_RED); + break; + case LED_BLUE: + GPIO_SetBits(GPIOD, GPIOD_BOARD_LED_BLUE); + break; + + } +} + +void leds_turn_off(int l) { + + switch (l) { + case LED_GREEN: + GPIO_ResetBits(GPIOD, GPIOD_BOARD_LED_GREEN); + break; + case LED_ORANGE: + GPIO_ResetBits(GPIOD, GPIOD_BOARD_LED_ORANGE); + break; + case LED_RED: + GPIO_ResetBits(GPIOD, GPIOD_BOARD_LED_RED); + break; + case LED_BLUE: + GPIO_ResetBits(GPIOD, GPIOD_BOARD_LED_BLUE); + break; + } +} diff --git a/src/glutt-o-logique/leds.h b/src/glutt-o-logique/leds.h new file mode 100644 index 0000000..869a032 --- /dev/null +++ b/src/glutt-o-logique/leds.h @@ -0,0 +1,4 @@ +#define GPIOD_BOARD_LED_GREEN GPIO_Pin_12 +#define GPIOD_BOARD_LED_ORANGE GPIO_Pin_13 +#define GPIOD_BOARD_LED_RED GPIO_Pin_14 +#define GPIOD_BOARD_LED_BLUE GPIO_Pin_15 diff --git a/src/glutt-o-logique/main.c b/src/glutt-o-logique/main.c new file mode 100644 index 0000000..21df1d0 --- /dev/null +++ b/src/glutt-o-logique/main.c @@ -0,0 +1,69 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 Matthias P. Braendli, Maximilien Cuony + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + +#include "stm32f4xx_conf.h" + +#include "leds.h" +#include "../../../common/src/Core/main.c" + + +void init() { + /* Initialise the onboard peripherals + * Four LEDs and one push-button + */ + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + + // Configure PD12, PD13, PD14 and PD15 in output pushpull mode + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = + GPIOD_BOARD_LED_GREEN | + GPIOD_BOARD_LED_ORANGE | + GPIOD_BOARD_LED_RED | + GPIOD_BOARD_LED_BLUE; + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOD, &GPIO_InitStructure); + + // Init PushButton + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // TODO is there an external pullup ? + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + + /* Setup Watchdog + * The IWDG runs at 32kHz. With a prescaler of 32 -> 1kHz. + * Counting to 2000 / 1000 = 2 seconds + */ + IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); + IWDG_SetPrescaler(IWDG_Prescaler_32); + IWDG_SetReload(2000); + IWDG_Enable(); +} diff --git a/src/glutt-o-logique/minmea.c b/src/glutt-o-logique/minmea.c new file mode 100644 index 0000000..10df198 --- /dev/null +++ b/src/glutt-o-logique/minmea.c @@ -0,0 +1 @@ +#include "../../../common/src/GPS/minmea.c" diff --git a/src/glutt-o-logique/pio.c b/src/glutt-o-logique/pio.c new file mode 100644 index 0000000..d8780fe --- /dev/null +++ b/src/glutt-o-logique/pio.c @@ -0,0 +1,187 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Matthias P. Braendli + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + +#include "stm32f4xx_rcc.h" +#include "stm32f4xx_gpio.h" + +/* See pio.txt for PIO allocation details */ + +/* On GPIO C */ +#define GPIO_PIN_QRP_n GPIO_Pin_1 +#define GPIO_PIN_TX GPIO_Pin_2 +#define GPIO_PIN_1750_n GPIO_Pin_4 +#define GPIO_PIN_MOD_OFF GPIO_Pin_5 +#define GPIO_PIN_SQ_n GPIO_Pin_6 +#define GPIO_PIN_U GPIO_Pin_8 +#define GPIO_PIN_QRP_out GPIO_Pin_9 +#define GPIO_PIN_D GPIO_Pin_11 +#define GPIO_PIN_REPLIE_n GPIO_Pin_13 +#define GPIO_PIN_FAX_n GPIO_Pin_14 + + +#define GPIOC_OUTPUT_PINS ( \ + GPIO_PIN_TX | \ + GPIO_PIN_MOD_OFF | \ + GPIO_PIN_QRP_out | \ + 0) + +#undef GPIOC_OPENDRAIN_PINS +#undef GPIOC_INPUT_PU_PINS + +#define GPIOC_INPUT_PINS ( \ + GPIO_PIN_QRP_n | \ + GPIO_PIN_1750_n | \ + GPIO_PIN_SQ_n | \ + GPIO_PIN_U | \ + GPIO_PIN_D | \ + GPIO_PIN_REPLIE_n | \ + 0 ) + +#include "GPIO/pio.h" +#include "Core/common.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +void read_fsm_input_task(void *pvParameters); + +struct fsm_input_signals_t pio_signals; + +void pio_init() +{ + GPIO_InitTypeDef GPIO_InitStructure; + + // Init pio + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Pin = GPIOC_OUTPUT_PINS; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOC, &GPIO_InitStructure); + +#if defined(GPIOC_OPENDRAIN_PINS) + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Pin = GPIOC_OPENDRAIN_PINS; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_Init(GPIOC, &GPIO_InitStructure); +#endif + +#if defined(GPIOC_INPUT_PU_PINS) + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Pin = GPIOC_INPUT_PU_PINS; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOC, &GPIO_InitStructure); +#endif + +#if defined(GPIOC_INPUT_PINS) + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Pin = GPIOC_INPUT_PINS; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOC, &GPIO_InitStructure); +#endif + + xTaskCreate( + read_fsm_input_task, + "TaskPIO", + configMINIMAL_STACK_SIZE, + (void*) NULL, + tskIDLE_PRIORITY + 2UL, + NULL); +} + +void pio_set_fsm_signals(struct fsm_input_signals_t* sig) +{ + *sig = pio_signals; +} + +void read_fsm_input_task(void *pvParameters) +{ + while (1) { + pio_signals.qrp = + GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_QRP_n) ? 0 : 1; + + pio_signals.tone_1750 = + GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_1750_n) ? 0 : 1; + + pio_signals.sq = + GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_SQ_n) ? 0 : 1; + + pio_signals.discrim_u = + GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_U) ? 1 : 0; + + pio_signals.discrim_d = + GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_D) ? 1 : 0; + + pio_signals.wind_generator_ok = + GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_REPLIE_n) ? 1 : 0; + + pio_signals.sstv_mode = + GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_FAX_n) ? 0 : 1; + + vTaskDelay(100 / portTICK_RATE_MS); + } +} + +void pio_set_tx(int on) +{ + if (on) { + GPIO_SetBits(GPIOC, GPIO_PIN_TX); + } + else { + GPIO_ResetBits(GPIOC, GPIO_PIN_TX); + } +} + +void pio_set_qrp(int on) +{ + if (on) { + GPIO_SetBits(GPIOC, GPIO_PIN_QRP_out); + } + else { + GPIO_ResetBits(GPIOC, GPIO_PIN_QRP_out); + } +} + +void pio_set_mod_off(int mod_off) +{ + if (mod_off) { + GPIO_SetBits(GPIOC, GPIO_PIN_MOD_OFF); + } + else { + GPIO_ResetBits(GPIOC, GPIO_PIN_MOD_OFF); + } +} + +int pio_read_button() { + return GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == Bit_SET; +} diff --git a/src/glutt-o-logique/temperature.c b/src/glutt-o-logique/temperature.c new file mode 100644 index 0000000..780a019 --- /dev/null +++ b/src/glutt-o-logique/temperature.c @@ -0,0 +1,93 @@ +/* On wire connection: PA1 + */ + +#define TEMPERATURE_ONEWIRE_PIN GPIO_Pin_1 + +#include "stm32f4xx_conf.h" +#include "stm32f4xx.h" + +#include "tm_stm32f4_ds18b20.h" +#include "tm_stm32f4_onewire.h" +#include "Core/delay.h" + + +#include "../../../common/src/GPIO/temperature.c" + +const TickType_t _temperature_delay = 60000 / portTICK_PERIOD_MS; // 60s + +static TM_OneWire_t tm_onewire; + + + +void ds18b20_init() { + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = TEMPERATURE_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); + + vTaskSuspendAll(); + TM_OneWire_Init(&tm_onewire, GPIOA, TEMPERATURE_ONEWIRE_PIN); + xTaskResumeAll(); +} + +int ds18b20_gettemp_one(float *temperature) { + + vTaskSuspendAll(); + + 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 + xTaskResumeAll(); + delay_ms(100); + vTaskSuspendAll(); + status = TM_DS18B20_Read(&tm_onewire, rom_addr, temperature); + } + + xTaskResumeAll(); + + 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_ms(5); + } + return status; +} + +static void temperature_task(void *pvParameters) { + + while (1) { + + if (!_temperature_valid) { + ds18b20_init(); + } + + if (ds18b20_gettemp(&_temperature_last_value)) { + _temperature_valid = 1; + } else { + _temperature_valid = 0; + } + + vTaskDelay(_temperature_delay); + + } +} diff --git a/src/glutt-o-logique/usart.c b/src/glutt-o-logique/usart.c new file mode 100644 index 0000000..d174719 --- /dev/null +++ b/src/glutt-o-logique/usart.c @@ -0,0 +1,156 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 Matthias P. Braendli + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + + +#include +#include +#include + +/* USART 3 on PD8 and PD9 + * See pio.txt for PIO allocation details */ +const uint16_t GPIOD_PIN_USART3_TX = GPIO_Pin_8; +const uint16_t GPIOD_PIN_USART3_RX = GPIO_Pin_9; + +/* USART 2 on PA2 and PA3 */ +const uint16_t GPIOA_PIN_USART2_RX = GPIO_Pin_3; +const uint16_t GPIOA_PIN_USART2_TX = GPIO_Pin_2; + +static void usart_puts(USART_TypeDef*, const char*); + +#include "../../../common/includes/GPIO/usart.h" +#include "../../../common/src/GPIO/usart.c" + + +void usart_init() { + // ============== 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 USART2_RECEIVE_ENABLE + // 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 = 1; + 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); +} + +void usart_gps_specific_init() { + + // ============== GPS USART =========== + // Setup GPIO D and connect to USART 3 + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIOD_PIN_USART3_RX | GPIOD_PIN_USART3_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(GPIOD, &GPIO_InitStruct); + + GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3); + + // Setup USART3 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(USART3, &USART_InitStruct); + + + // enable the USART3 receive interrupt + USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); + + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_SetPriority(USART3_IRQn, 6); + + // finally this enables the complete USART3 peripheral + USART_Cmd(USART3, ENABLE); +} + +// Make sure Tasks are suspended when this is called! +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++; + } +} + +void USART3_IRQHandler(void) { + if (USART_GetITStatus(USART3, USART_IT_RXNE)) { + char t = USART3->DR; + usart_gps_process_char(t); + } +} + +void USART2_IRQHandler(void) { + if (USART_GetITStatus(USART2, USART_IT_RXNE)) { + char t = USART2->DR; + usart_process_char(t); + } +} diff --git a/src/stm32f/.gitignore b/src/stm32f/.gitignore deleted file mode 100644 index 6533942..0000000 --- a/src/stm32f/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vc.h diff --git a/src/stm32f/FreeRTOS b/src/stm32f/FreeRTOS deleted file mode 120000 index 51f4e96..0000000 --- a/src/stm32f/FreeRTOS +++ /dev/null @@ -1 +0,0 @@ -../FreeRTOS \ No newline at end of file diff --git a/src/stm32f/Makefile b/src/stm32f/Makefile deleted file mode 100644 index 29bf265..0000000 --- a/src/stm32f/Makefile +++ /dev/null @@ -1,131 +0,0 @@ -### -# 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=. -ODIR=obj - -### -# 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%) -I ../common/includes/ -I ./includes/ -# Create object list -OBJECTS=$(ASOURCES:%.s=%.o) -OBJECTS+=$(CSOURCES:%.c=obj/%.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) - -dir_guard=@mkdir -p $(@D) - -obj/%.o: %.c $(INC) - $(dir_guard) - $(CC) $(CFLAGS) $< -o $@ - -obj/%.o: %.s - $(dir_guard) - $(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 - echo >> vc.h - echo >> 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/stm32f/bin/.gitignore b/src/stm32f/bin/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/src/stm32f/bin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/src/stm32f/bsp b/src/stm32f/bsp deleted file mode 120000 index 5d9120a..0000000 --- a/src/stm32f/bsp +++ /dev/null @@ -1 +0,0 @@ -../bsp \ No newline at end of file diff --git a/src/stm32f/includes/GPIO/leds.h b/src/stm32f/includes/GPIO/leds.h deleted file mode 100644 index 869a032..0000000 --- a/src/stm32f/includes/GPIO/leds.h +++ /dev/null @@ -1,4 +0,0 @@ -#define GPIOD_BOARD_LED_GREEN GPIO_Pin_12 -#define GPIOD_BOARD_LED_ORANGE GPIO_Pin_13 -#define GPIOD_BOARD_LED_RED GPIO_Pin_14 -#define GPIOD_BOARD_LED_BLUE GPIO_Pin_15 diff --git a/src/stm32f/obj/.gitignore b/src/stm32f/obj/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/src/stm32f/obj/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/src/stm32f/src/Audio/audio.c b/src/stm32f/src/Audio/audio.c deleted file mode 100644 index bdb2961..0000000 --- a/src/stm32f/src/Audio/audio.c +++ /dev/null @@ -1,220 +0,0 @@ -#include "GPIO/i2c.h" -#include "stm32f4xx_conf.h" -#include "stm32f4xx.h" - -#include "../../../common/src/Audio/audio.c" - -void audio_initialize_platform(int plln, int pllr, int i2sdiv, int i2sodd, int rate) { - - GPIO_InitTypeDef GPIO_InitStructure; - - // Turn on peripherals. - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); - RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); - - // Assume I2C is set up - - // Configure reset pin. - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOD, &GPIO_InitStructure); - - // Configure I2S MCK, SCK, SD pins. - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_10 | GPIO_Pin_12; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOC, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_SPI3); - GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3); - GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3); - - // Configure I2S WS pin. - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_SPI3); - - // Reset the codec. - GPIO_ResetBits(GPIOD, GPIO_Pin_4); - for (volatile int i = 0; i < 0x4fff; i++) { - __asm__ volatile("nop"); - } - GPIO_SetBits(GPIOD, GPIO_Pin_4); - - // Configure codec. - audio_write_register(0x02, 0x01); // Keep codec powered off. - audio_write_register(0x04, 0xaf); // SPK always off and HP always on. - - audio_write_register(0x05, 0x81); // Clock configuration: Auto detection. - audio_write_register(0x06, 0x04); // Set slave mode and Philips audio standard. - - // Power on the codec. - audio_write_register(0x02, 0x9e); - - // Configure codec for fast shutdown. - audio_write_register(0x0a, 0x00); // Disable the analog soft ramp. - audio_write_register(0x0e, 0x04); // Disable the digital soft ramp. - - audio_write_register(0x27, 0x00); // Disable the limiter attack level. - audio_write_register(0x1f, 0x0f); // Adjust bass and treble levels. - - audio_write_register(0x1a, 0x0a); // Adjust PCM volume level. - audio_write_register(0x1b, 0x0a); - - // Disable I2S. - SPI3 ->I2SCFGR = 0; - - // I2S clock configuration - RCC ->CFGR &= ~RCC_CFGR_I2SSRC; // PLLI2S clock used as I2S clock source. - RCC ->PLLI2SCFGR = (pllr << 28) | (plln << 6); - - // Enable PLLI2S and wait until it is ready. - RCC ->CR |= RCC_CR_PLLI2SON; - while (!(RCC ->CR & RCC_CR_PLLI2SRDY )) - ; - - // Configure I2S. - SPI3 ->I2SPR = i2sdiv | (i2sodd << 8) | SPI_I2SPR_MCKOE; - SPI3 ->I2SCFGR = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1 - | SPI_I2SCFGR_I2SE; // Master transmitter, Phillips mode, 16 bit values, clock polarity low, enable. - -} - -void audio_on() { - audio_write_register(0x02, 0x9e); - SPI3 ->I2SCFGR = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1 - | SPI_I2SCFGR_I2SE; // Master transmitter, Phillips mode, 16 bit values, clock polarity low, enable. -} - -void audio_off() { - audio_write_register(0x02, 0x9f); - SPI3 ->I2SCFGR = 0; -} - -void audio_set_volume(int volume) { - audio_write_register(0x20, (volume + 0x19) & 0xff); - audio_write_register(0x21, (volume + 0x19) & 0xff); -} - -void audio_output_sample(int16_t sample) { - while (!(SPI3 ->SR & SPI_SR_TXE )) - ; - SPI3 ->DR = sample; -} - - -void audio_output_sample_without_blocking(int16_t sample) { - SPI3 ->DR = sample; -} - -void audio_play_with_callback(AudioCallbackFunction *callback, void *context) { - audio_stop_dma(); - - NVIC_EnableIRQ(DMA1_Stream7_IRQn); - NVIC_SetPriority(DMA1_Stream7_IRQn, 5); - - SPI3 ->CR2 |= SPI_CR2_TXDMAEN; // Enable I2S TX DMA request. - - callback_function = callback; - callback_context = context; - buffer_number = 0; - - if (callback_function) - callback_function(callback_context, buffer_number); -} - -void audio_stop() { - audio_stop_dma(); - SPI3 ->CR2 &= ~SPI_CR2_TXDMAEN; // Disable I2S TX DMA request. - NVIC_DisableIRQ(DMA1_Stream7_IRQn); - callback_function = NULL; -} - -void audio_provide_buffer(void *samples, int numsamples) { - while (!audio_provide_buffer_without_blocking(samples, numsamples)) - __asm__ volatile ("wfi"); -} - -bool audio_provide_buffer_without_blocking(void *samples, int numsamples) { - if (next_buffer_samples) - return false; - - NVIC_DisableIRQ(DMA1_Stream7_IRQn); - - next_buffer_samples = samples; - next_buffer_length = numsamples; - - if (!dma_running) - audio_start_dma_and_request_buffers(); - - NVIC_EnableIRQ(DMA1_Stream7_IRQn); - - return true; -} - -static void audio_start_dma_and_request_buffers() { - // Configure DMA stream. - DMA1_Stream7 ->CR = (0 * DMA_SxCR_CHSEL_0 ) | // Channel 0 - (1 * DMA_SxCR_PL_0 ) | // Priority 1 - (1 * DMA_SxCR_PSIZE_0 ) | // PSIZE = 16 bit - (1 * DMA_SxCR_MSIZE_0 ) | // MSIZE = 16 bit - DMA_SxCR_MINC | // Increase memory address - (1 * DMA_SxCR_DIR_0 ) | // Memory to peripheral - DMA_SxCR_TCIE; // Transfer complete interrupt - DMA1_Stream7 ->NDTR = next_buffer_length; - DMA1_Stream7 ->PAR = (uint32_t) &SPI3 ->DR; - DMA1_Stream7 ->M0AR = (uint32_t) next_buffer_samples; - DMA1_Stream7 ->FCR = DMA_SxFCR_DMDIS; - DMA1_Stream7 ->CR |= DMA_SxCR_EN; - - // Update state. - next_buffer_samples = NULL; - buffer_number ^= 1; - dma_running = true; - - // Invoke callback if it exists to queue up another buffer. - if (callback_function) - callback_function(callback_context, buffer_number); -} - -static void audio_stop_dma() { - DMA1_Stream7 ->CR &= ~DMA_SxCR_EN; // Disable DMA stream. - while (DMA1_Stream7 ->CR & DMA_SxCR_EN ) - ; // Wait for DMA stream to stop. - - dma_running = false; -} - -void DMA1_Stream7_IRQHandler() { - DMA1 ->HIFCR |= DMA_HIFCR_CTCIF7; // Clear interrupt flag. - - if (next_buffer_samples) { - audio_start_dma_and_request_buffers(); - } else { - dma_running = false; - } -} - -// Warning: don't i2c_write call from IRQ handler ! -static void audio_write_register(uint8_t address, uint8_t value) -{ - const uint8_t device = 0x4a; - const uint8_t data[2] = {address, value}; - i2c_transaction_start(); - i2c_write(device, data, 2); - i2c_transaction_end(); -} - diff --git a/src/stm32f/src/Audio/cw.c b/src/stm32f/src/Audio/cw.c deleted file mode 100644 index 028ae82..0000000 --- a/src/stm32f/src/Audio/cw.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "../../../common/src/Audio/cw.c" - -void cw_message_sent(const char* str) { -} diff --git a/src/stm32f/src/Core/FreeRTOSConfig.h b/src/stm32f/src/Core/FreeRTOSConfig.h deleted file mode 100644 index 8d6f128..0000000 --- a/src/stm32f/src/Core/FreeRTOSConfig.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "../../../common/src/Core/FreeRTOSConfig.h" - -#define configCHECK_FOR_STACK_OVERFLOW 2 // Default: 2 diff --git a/src/stm32f/src/Core/common.c b/src/stm32f/src/Core/common.c deleted file mode 100644 index a647d26..0000000 --- a/src/stm32f/src/Core/common.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -#include "../../../common/src/Core/common.c" - -void hard_fault_handler_extra() { - usart_debug("SCB_SHCSR = %x\n", SCB->SHCSR); -} diff --git a/src/stm32f/src/Core/delay.c b/src/stm32f/src/Core/delay.c deleted file mode 100644 index 59030c4..0000000 --- a/src/stm32f/src/Core/delay.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 Matthias P. Braendli, Maximilien Cuony - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*/ - -#include "delay.h" -#include "stm32f4xx_conf.h" -#include "stm32f4xx.h" - -uint32_t delay_multiplier = 1; - -void delay_us(uint32_t micros) -{ - micros = micros * delay_multiplier - 10; - while (micros--); -} - -void delay_ms(uint32_t millis) -{ - for (int i = 0; i < 1000; i++) { - delay_us(millis); - } -} - -void delay_init() -{ - RCC_ClocksTypeDef RCC_Clocks; - RCC_GetClocksFreq(&RCC_Clocks); - - delay_multiplier = RCC_Clocks.HCLK_Frequency / 4000000; -} - diff --git a/src/stm32f/src/Core/fsm.c b/src/stm32f/src/Core/fsm.c deleted file mode 100644 index 99413ba..0000000 --- a/src/stm32f/src/Core/fsm.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "../../../common/src/Core/fsm.c" - - -void fsm_state_switched(char * new_state) { - usart_debug_puts("FSM: "); - usart_debug_puts(new_state); - usart_debug_puts("\r\n"); -} diff --git a/src/stm32f/src/Core/main.c b/src/stm32f/src/Core/main.c deleted file mode 100644 index d63f540..0000000 --- a/src/stm32f/src/Core/main.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 Matthias P. Braendli, Maximilien Cuony - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*/ - -#include "stm32f4xx_conf.h" - -#include "../../../stm32f/includes/GPIO/leds.h" -#include "../../../common/src/Core/main.c" - - -void init() { - /* Initialise the onboard peripherals - * Four LEDs and one push-button - */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); - - // Configure PD12, PD13, PD14 and PD15 in output pushpull mode - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = - GPIOD_BOARD_LED_GREEN | - GPIOD_BOARD_LED_ORANGE | - GPIOD_BOARD_LED_RED | - GPIOD_BOARD_LED_BLUE; - - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOD, &GPIO_InitStructure); - - // Init PushButton - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // TODO is there an external pullup ? - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - - /* Setup Watchdog - * The IWDG runs at 32kHz. With a prescaler of 32 -> 1kHz. - * Counting to 2000 / 1000 = 2 seconds - */ - IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); - IWDG_SetPrescaler(IWDG_Prescaler_32); - IWDG_SetReload(2000); - IWDG_Enable(); -} diff --git a/src/stm32f/src/GPIO/i2c.c b/src/stm32f/src/GPIO/i2c.c deleted file mode 100644 index 750f5de..0000000 --- a/src/stm32f/src/GPIO/i2c.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015 Matthias P. Braendli - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*/ - -#include "GPIO/i2c.h" -#include "Core/common.h" - -#include "stm32f4xx_conf.h" -#include "stm32f4xx_i2c.h" -#include "stm32f4xx.h" -#include "FreeRTOS.h" -#include "FreeRTOSConfig.h" -#include "task.h" -#include "semphr.h" -#include "GPIO/usart.h" - -/* I2C 1 on PB9 and PB6 - * See pio.txt for PIO allocation details */ -const uint16_t GPIOB_PIN_SDA = GPIO_Pin_9; -const uint16_t GPIOB_PIN_SCL = GPIO_Pin_6; - - -static int i2c_init_done = 0; -static int i2c_error = 0; - -static I2C_TypeDef* const I2Cx = I2C1; - -static SemaphoreHandle_t i2c_semaphore; - -static void i2c_device_init(void); - -/* According to I2C spec UM10204: - * 3.1.16 Bus clear - * In the unlikely event where the clock (SCL) is stuck LOW, the preferential - * procedure is to reset the bus using the HW reset signal if your I2C devices - * have HW reset inputs. If the I2C devices do not have HW reset inputs, cycle - * power to the devices to activate the mandatory internal Power-On Reset (POR) - * circuit. - * - * If the data line (SDA) is stuck LOW, the master should send nine clock - * pulses. The device that held the bus LOW should release it sometime within - * those nine clocks. If not, then use the HW reset or cycle power to clear the - * bus. - */ -static void i2c_recover_from_lockup(void) -{ - usart_debug_puts("ERROR: I2C lockup\r\n"); - - I2C_SoftwareResetCmd(I2Cx, ENABLE); - - // Configure I2C SCL and SDA pins. - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = GPIOB_PIN_SCL | GPIOB_PIN_SDA; - 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(GPIOB, &GPIO_InitStructure); - - const TickType_t delay = 5 / portTICK_PERIOD_MS; - - GPIO_SetBits(GPIOB, GPIOB_PIN_SDA | GPIOB_PIN_SCL); - vTaskDelay(delay); - - for (int i = 0; i < 10; i++) { - GPIO_ResetBits(GPIOB, GPIOB_PIN_SCL); - vTaskDelay(delay); - GPIO_SetBits(GPIOB, GPIOB_PIN_SCL); - vTaskDelay(delay); - } - - I2C_SoftwareResetCmd(I2Cx, DISABLE); - - i2c_device_init(); -} - -static void i2c_device_init(void) -{ - // Configure I2C SCL and SDA pins. - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = GPIOB_PIN_SCL | GPIOB_PIN_SDA; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); - GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1); - - // Reset I2C. - RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); - - // configure I2C1 - I2C_InitTypeDef I2C_InitStruct; - I2C_InitStruct.I2C_ClockSpeed = 100000; //Hz - I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; - I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle - I2C_InitStruct.I2C_OwnAddress1 = 0x00; // not relevant in master mode - - // disable acknowledge when reading (can be changed later on) - I2C_InitStruct.I2C_Ack = I2C_Ack_Disable; - - I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; - I2C_Init(I2C1, &I2C_InitStruct); - - // enable I2C1 - I2C_Cmd(I2C1, ENABLE); -} - -void i2c_init() -{ - if (i2c_init_done == 1) { - return; - } - - i2c_semaphore = xSemaphoreCreateBinary(); - - if ( i2c_semaphore == NULL ) { - trigger_fault(FAULT_SOURCE_I2C); - } - else { - xSemaphoreGive(i2c_semaphore); - } - - RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); - - i2c_device_init(); - i2c_init_done = 1; -} - -static int i2c_check_busy_flag(void) -{ - const TickType_t i2c_timeout = 1000ul / portTICK_PERIOD_MS; - const TickType_t time_start = xTaskGetTickCount(); - - while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)) { - const TickType_t time_now = xTaskGetTickCount(); - - if (time_now - time_start > i2c_timeout) { - i2c_error = 1; - return 0; - } - } - - return 1; -} - -static int i2c_check_event(uint32_t event) -{ - const TickType_t i2c_timeout = 1000ul / portTICK_PERIOD_MS; - const TickType_t time_start = xTaskGetTickCount(); - - while (!I2C_CheckEvent(I2Cx, event)) { - const TickType_t time_now = xTaskGetTickCount(); - - if (time_now - time_start > i2c_timeout) { - i2c_error = 1; - return 0; - } - } - - return 1; -} - -static int i2c_start(uint8_t device, uint8_t direction) -{ - I2C_GenerateSTART(I2Cx, ENABLE); - - // wait for bus free - if (!i2c_check_event(I2C_EVENT_MASTER_MODE_SELECT)) { - I2C_GenerateSTART(I2Cx, DISABLE); - return 0; - } - - I2C_Send7bitAddress(I2Cx, device << 1, direction); - - /* wait for I2C1 EV6, check if - * either Slave has acknowledged Master transmitter or - * Master receiver mode, depending on the transmission - * direction - */ - uint32_t event = 0; - if (direction == I2C_Direction_Transmitter) { - event = I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED; - } - else if (direction == I2C_Direction_Receiver) { - event = I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED; - } - else { - trigger_fault(FAULT_SOURCE_I2C); - } - - if (!i2c_check_event(event)) { - return 0; - } - - return 1; -} - -static int i2c_send(uint8_t data) -{ - I2C_SendData(I2Cx, data); - - // wait for I2C1 EV8_2 --> byte has been transmitted - return i2c_check_event(I2C_EVENT_MASTER_BYTE_TRANSMITTED); -} - -int i2c_write(uint8_t device, const uint8_t *txbuf, int len) -{ - if (i2c_init_done == 0) { - trigger_fault(FAULT_SOURCE_I2C); - } - - int success = i2c_check_busy_flag(); - - if (success) { - success = i2c_start(device, I2C_Direction_Transmitter); - } - - if (success) { - for (int i = 0; i < len; i++) { - success = i2c_send(txbuf[i]); - if (!success) { - break; - } - } - - I2C_GenerateSTOP(I2Cx, ENABLE); - success = i2c_check_event(I2C_EVENT_MASTER_BYTE_TRANSMITTED); - } - - return success; -} - -static int i2c_read_nobuscheck(uint8_t device, uint8_t *rxbuf, int len) -{ - if (i2c_init_done == 0) { - trigger_fault(FAULT_SOURCE_I2C); - } - - if (i2c_start(device, I2C_Direction_Receiver)) { - for (int i = 0; i < len; i++) { - if (i == len-1) { - I2C_AcknowledgeConfig(I2Cx, DISABLE); - } - else { - I2C_AcknowledgeConfig(I2Cx, ENABLE); - } - - // wait until one byte has been received, possibly timout - if (!i2c_check_event(I2C_EVENT_MASTER_BYTE_RECEIVED)) { - I2C_GenerateSTOP(I2Cx, ENABLE); - return 0; - } - - if (i == len-1) { - I2C_GenerateSTOP(I2Cx, ENABLE); - } - - rxbuf[i] = I2C_ReceiveData(I2Cx); - } - return len; - } - - return 0; -} - -int i2c_read(uint8_t device, uint8_t *rxbuf, int len) -{ - int success = i2c_check_busy_flag(); - - if (success) { - success = i2c_read_nobuscheck(device, rxbuf, len); - } - - return success; -} - -int i2c_read_from(uint8_t device, uint8_t address, uint8_t *rxbuf, int len) -{ - if (i2c_init_done == 0) { - trigger_fault(FAULT_SOURCE_I2C); - } - - int success = i2c_check_busy_flag(); - - if (success) { - success = i2c_start(device, I2C_Direction_Transmitter); - } - - if (success) { - success = i2c_send(address); - } - // Don't do a STOP - - if (success) { - success = i2c_read_nobuscheck(device, rxbuf, len); - } - - return success; -} - - - -void i2c_transaction_start() -{ - if (i2c_init_done == 0) { - trigger_fault(FAULT_SOURCE_I2C); - } - xSemaphoreTake(i2c_semaphore, portMAX_DELAY); -} - -void i2c_transaction_end() -{ - if (i2c_init_done == 0) { - trigger_fault(FAULT_SOURCE_I2C); - } - - if ( i2c_error ) { - i2c_recover_from_lockup(); - - i2c_error = 0; - } - - xSemaphoreGive(i2c_semaphore); -} - diff --git a/src/stm32f/src/GPIO/leds.c b/src/stm32f/src/GPIO/leds.c deleted file mode 100644 index 291b650..0000000 --- a/src/stm32f/src/GPIO/leds.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../../../common/src/GPIO/leds.c" - -#include "stm32f4xx_conf.h" - -#include "../../../stm32f/includes/GPIO/leds.h" - -void leds_turn_on(int l) { - - switch (l) { - case LED_GREEN: - GPIO_SetBits(GPIOD, GPIOD_BOARD_LED_GREEN); - break; - case LED_ORANGE: - GPIO_SetBits(GPIOD, GPIOD_BOARD_LED_ORANGE); - break; - case LED_RED: - GPIO_SetBits(GPIOD, GPIOD_BOARD_LED_RED); - break; - case LED_BLUE: - GPIO_SetBits(GPIOD, GPIOD_BOARD_LED_BLUE); - break; - - } -} - -void leds_turn_off(int l) { - - switch (l) { - case LED_GREEN: - GPIO_ResetBits(GPIOD, GPIOD_BOARD_LED_GREEN); - break; - case LED_ORANGE: - GPIO_ResetBits(GPIOD, GPIOD_BOARD_LED_ORANGE); - break; - case LED_RED: - GPIO_ResetBits(GPIOD, GPIOD_BOARD_LED_RED); - break; - case LED_BLUE: - GPIO_ResetBits(GPIOD, GPIOD_BOARD_LED_BLUE); - break; - } -} diff --git a/src/stm32f/src/GPIO/pio.c b/src/stm32f/src/GPIO/pio.c deleted file mode 100644 index d8780fe..0000000 --- a/src/stm32f/src/GPIO/pio.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015 Matthias P. Braendli - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*/ - -#include "stm32f4xx_rcc.h" -#include "stm32f4xx_gpio.h" - -/* See pio.txt for PIO allocation details */ - -/* On GPIO C */ -#define GPIO_PIN_QRP_n GPIO_Pin_1 -#define GPIO_PIN_TX GPIO_Pin_2 -#define GPIO_PIN_1750_n GPIO_Pin_4 -#define GPIO_PIN_MOD_OFF GPIO_Pin_5 -#define GPIO_PIN_SQ_n GPIO_Pin_6 -#define GPIO_PIN_U GPIO_Pin_8 -#define GPIO_PIN_QRP_out GPIO_Pin_9 -#define GPIO_PIN_D GPIO_Pin_11 -#define GPIO_PIN_REPLIE_n GPIO_Pin_13 -#define GPIO_PIN_FAX_n GPIO_Pin_14 - - -#define GPIOC_OUTPUT_PINS ( \ - GPIO_PIN_TX | \ - GPIO_PIN_MOD_OFF | \ - GPIO_PIN_QRP_out | \ - 0) - -#undef GPIOC_OPENDRAIN_PINS -#undef GPIOC_INPUT_PU_PINS - -#define GPIOC_INPUT_PINS ( \ - GPIO_PIN_QRP_n | \ - GPIO_PIN_1750_n | \ - GPIO_PIN_SQ_n | \ - GPIO_PIN_U | \ - GPIO_PIN_D | \ - GPIO_PIN_REPLIE_n | \ - 0 ) - -#include "GPIO/pio.h" -#include "Core/common.h" -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "semphr.h" - -void read_fsm_input_task(void *pvParameters); - -struct fsm_input_signals_t pio_signals; - -void pio_init() -{ - GPIO_InitTypeDef GPIO_InitStructure; - - // Init pio - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); - - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_Pin = GPIOC_OUTPUT_PINS; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_Init(GPIOC, &GPIO_InitStructure); - -#if defined(GPIOC_OPENDRAIN_PINS) - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_Pin = GPIOC_OPENDRAIN_PINS; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_Init(GPIOC, &GPIO_InitStructure); -#endif - -#if defined(GPIOC_INPUT_PU_PINS) - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_Pin = GPIOC_INPUT_PU_PINS; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_Init(GPIOC, &GPIO_InitStructure); -#endif - -#if defined(GPIOC_INPUT_PINS) - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_Pin = GPIOC_INPUT_PINS; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_Init(GPIOC, &GPIO_InitStructure); -#endif - - xTaskCreate( - read_fsm_input_task, - "TaskPIO", - configMINIMAL_STACK_SIZE, - (void*) NULL, - tskIDLE_PRIORITY + 2UL, - NULL); -} - -void pio_set_fsm_signals(struct fsm_input_signals_t* sig) -{ - *sig = pio_signals; -} - -void read_fsm_input_task(void *pvParameters) -{ - while (1) { - pio_signals.qrp = - GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_QRP_n) ? 0 : 1; - - pio_signals.tone_1750 = - GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_1750_n) ? 0 : 1; - - pio_signals.sq = - GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_SQ_n) ? 0 : 1; - - pio_signals.discrim_u = - GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_U) ? 1 : 0; - - pio_signals.discrim_d = - GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_D) ? 1 : 0; - - pio_signals.wind_generator_ok = - GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_REPLIE_n) ? 1 : 0; - - pio_signals.sstv_mode = - GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_FAX_n) ? 0 : 1; - - vTaskDelay(100 / portTICK_RATE_MS); - } -} - -void pio_set_tx(int on) -{ - if (on) { - GPIO_SetBits(GPIOC, GPIO_PIN_TX); - } - else { - GPIO_ResetBits(GPIOC, GPIO_PIN_TX); - } -} - -void pio_set_qrp(int on) -{ - if (on) { - GPIO_SetBits(GPIOC, GPIO_PIN_QRP_out); - } - else { - GPIO_ResetBits(GPIOC, GPIO_PIN_QRP_out); - } -} - -void pio_set_mod_off(int mod_off) -{ - if (mod_off) { - GPIO_SetBits(GPIOC, GPIO_PIN_MOD_OFF); - } - else { - GPIO_ResetBits(GPIOC, GPIO_PIN_MOD_OFF); - } -} - -int pio_read_button() { - return GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == Bit_SET; -} diff --git a/src/stm32f/src/GPIO/temperature.c b/src/stm32f/src/GPIO/temperature.c deleted file mode 100644 index 780a019..0000000 --- a/src/stm32f/src/GPIO/temperature.c +++ /dev/null @@ -1,93 +0,0 @@ -/* On wire connection: PA1 - */ - -#define TEMPERATURE_ONEWIRE_PIN GPIO_Pin_1 - -#include "stm32f4xx_conf.h" -#include "stm32f4xx.h" - -#include "tm_stm32f4_ds18b20.h" -#include "tm_stm32f4_onewire.h" -#include "Core/delay.h" - - -#include "../../../common/src/GPIO/temperature.c" - -const TickType_t _temperature_delay = 60000 / portTICK_PERIOD_MS; // 60s - -static TM_OneWire_t tm_onewire; - - - -void ds18b20_init() { - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = TEMPERATURE_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); - - vTaskSuspendAll(); - TM_OneWire_Init(&tm_onewire, GPIOA, TEMPERATURE_ONEWIRE_PIN); - xTaskResumeAll(); -} - -int ds18b20_gettemp_one(float *temperature) { - - vTaskSuspendAll(); - - 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 - xTaskResumeAll(); - delay_ms(100); - vTaskSuspendAll(); - status = TM_DS18B20_Read(&tm_onewire, rom_addr, temperature); - } - - xTaskResumeAll(); - - 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_ms(5); - } - return status; -} - -static void temperature_task(void *pvParameters) { - - while (1) { - - if (!_temperature_valid) { - ds18b20_init(); - } - - if (ds18b20_gettemp(&_temperature_last_value)) { - _temperature_valid = 1; - } else { - _temperature_valid = 0; - } - - vTaskDelay(_temperature_delay); - - } -} diff --git a/src/stm32f/src/GPIO/tm_stm32f4_ds18b20.c b/src/stm32f/src/GPIO/tm_stm32f4_ds18b20.c deleted file mode 120000 index ffa5c2a..0000000 --- a/src/stm32f/src/GPIO/tm_stm32f4_ds18b20.c +++ /dev/null @@ -1 +0,0 @@ -../../../ds18b20/tm_stm32f4_ds18b20.c \ No newline at end of file diff --git a/src/stm32f/src/GPIO/tm_stm32f4_ds18b20.h b/src/stm32f/src/GPIO/tm_stm32f4_ds18b20.h deleted file mode 120000 index 51c9ece..0000000 --- a/src/stm32f/src/GPIO/tm_stm32f4_ds18b20.h +++ /dev/null @@ -1 +0,0 @@ -../../../ds18b20/tm_stm32f4_ds18b20.h \ No newline at end of file diff --git a/src/stm32f/src/GPIO/tm_stm32f4_onewire.c b/src/stm32f/src/GPIO/tm_stm32f4_onewire.c deleted file mode 120000 index 241eefa..0000000 --- a/src/stm32f/src/GPIO/tm_stm32f4_onewire.c +++ /dev/null @@ -1 +0,0 @@ -../../../ds18b20/tm_stm32f4_onewire.c \ No newline at end of file diff --git a/src/stm32f/src/GPIO/tm_stm32f4_onewire.h b/src/stm32f/src/GPIO/tm_stm32f4_onewire.h deleted file mode 120000 index 81ebf8e..0000000 --- a/src/stm32f/src/GPIO/tm_stm32f4_onewire.h +++ /dev/null @@ -1 +0,0 @@ -../../../ds18b20/tm_stm32f4_onewire.h \ No newline at end of file diff --git a/src/stm32f/src/GPIO/usart.c b/src/stm32f/src/GPIO/usart.c deleted file mode 100644 index d174719..0000000 --- a/src/stm32f/src/GPIO/usart.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 Matthias P. Braendli - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. -*/ - - -#include -#include -#include - -/* USART 3 on PD8 and PD9 - * See pio.txt for PIO allocation details */ -const uint16_t GPIOD_PIN_USART3_TX = GPIO_Pin_8; -const uint16_t GPIOD_PIN_USART3_RX = GPIO_Pin_9; - -/* USART 2 on PA2 and PA3 */ -const uint16_t GPIOA_PIN_USART2_RX = GPIO_Pin_3; -const uint16_t GPIOA_PIN_USART2_TX = GPIO_Pin_2; - -static void usart_puts(USART_TypeDef*, const char*); - -#include "../../../common/includes/GPIO/usart.h" -#include "../../../common/src/GPIO/usart.c" - - -void usart_init() { - // ============== 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 USART2_RECEIVE_ENABLE - // 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 = 1; - 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); -} - -void usart_gps_specific_init() { - - // ============== GPS USART =========== - // Setup GPIO D and connect to USART 3 - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); - - GPIO_InitTypeDef GPIO_InitStruct; - GPIO_InitStruct.GPIO_Pin = GPIOD_PIN_USART3_RX | GPIOD_PIN_USART3_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(GPIOD, &GPIO_InitStruct); - - GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3); - GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3); - - // Setup USART3 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(USART3, &USART_InitStruct); - - - // enable the USART3 receive interrupt - USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); - - NVIC_InitTypeDef NVIC_InitStructure; - NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - NVIC_SetPriority(USART3_IRQn, 6); - - // finally this enables the complete USART3 peripheral - USART_Cmd(USART3, ENABLE); -} - -// Make sure Tasks are suspended when this is called! -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++; - } -} - -void USART3_IRQHandler(void) { - if (USART_GetITStatus(USART3, USART_IT_RXNE)) { - char t = USART3->DR; - usart_gps_process_char(t); - } -} - -void USART2_IRQHandler(void) { - if (USART_GetITStatus(USART2, USART_IT_RXNE)) { - char t = USART2->DR; - usart_process_char(t); - } -} diff --git a/src/stm32f/src/GPS/gps.c b/src/stm32f/src/GPS/gps.c deleted file mode 100644 index 10afe88..0000000 --- a/src/stm32f/src/GPS/gps.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "stm32f4xx_conf.h" -#include "stm32f4xx.h" - -#include "../../../common/src/GPS/gps.c" diff --git a/src/stm32f/src/GPS/minema.c b/src/stm32f/src/GPS/minema.c deleted file mode 100644 index 10df198..0000000 --- a/src/stm32f/src/GPS/minema.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../../common/src/GPS/minmea.c" -- cgit v1.2.3