Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nickshl/DevBoy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornickshl <nicolai.shlapunov@gmail.com>2019-01-18 08:55:56 +0300
committernickshl <nicolai.shlapunov@gmail.com>2019-01-18 08:55:56 +0300
commit23d9320207b1065f6fb7f56516287bed95923dfd (patch)
tree4a5140980e921f6165db8f4816d54a5e64c4c81c
parentd5784223866b90221b6ccd52cb56f62164e344e1 (diff)
Some updates
-rw-r--r--STM32F415APP/.cproject16
-rw-r--r--STM32F415APP/Application/Application.cpp119
-rw-r--r--STM32F415APP/Application/Tetris.h2
-rw-r--r--STM32F415APP/DevCore/DevCfg.h7
-rw-r--r--STM32F415APP/DevCore/Display/DisplayDrv.cpp92
-rw-r--r--STM32F415APP/DevCore/Display/Image.cpp2
-rw-r--r--STM32F415APP/DevCore/Display/Image.h21
-rw-r--r--STM32F415APP/DevCore/Display/Primitives.cpp4
-rw-r--r--STM32F415APP/DevCore/Display/Primitives.h4
-rw-r--r--STM32F415APP/DevCore/Drivers/StHalIic.cpp37
-rw-r--r--STM32F415APP/DevCore/Drivers/StHalSpi.cpp335
-rw-r--r--STM32F415APP/DevCore/Drivers/StHalSpi.h162
-rw-r--r--STM32F415APP/DevCore/Drivers/StHalUart.cpp202
-rw-r--r--STM32F415APP/DevCore/Drivers/StHalUart.h131
-rw-r--r--STM32F415APP/DevCore/FreeRtosWrapper/Rtos.cpp14
-rw-r--r--STM32F415APP/DevCore/Interfaces/ISpi.h156
-rw-r--r--STM32F415APP/DevCore/Interfaces/IUart.h104
-rw-r--r--STM32F415APP/DevCore/Libraries/BoschBME280.cpp31
-rw-r--r--STM32F415APP/DevCore/Libraries/BoschBME280.h30
-rw-r--r--STM32F415APP/DevCore/Libraries/Eeprom24.cpp2
-rw-r--r--STM32F415APP/DevCore/Libraries/Mlx90614.cpp112
-rw-r--r--STM32F415APP/DevCore/Libraries/Mlx90614.h149
-rw-r--r--STM32F415APP/DevCore/Libraries/Tcs34725.cpp439
-rw-r--r--STM32F415APP/DevCore/Libraries/Tcs34725.h298
-rw-r--r--STM32F415APP/DevCore/Tasks/InputDrv.cpp67
-rw-r--r--STM32F415APP/DevCore/Tasks/InputDrv.h21
-rw-r--r--STM32F415APP/DevCore/UiEngine/UiButton.h10
27 files changed, 2427 insertions, 140 deletions
diff --git a/STM32F415APP/.cproject b/STM32F415APP/.cproject
index 1de644e..ace207c 100644
--- a/STM32F415APP/.cproject
+++ b/STM32F415APP/.cproject
@@ -137,12 +137,22 @@
<option id="fr.ac6.managedbuild.option.gnu.cross.instructionSet.653372639.1706570434" name="Instruction Set" superClass="fr.ac6.managedbuild.option.gnu.cross.instructionSet.653372639"/>
<option id="fr.ac6.managedbuild.option.gnu.cross.fpu.715560000.1505047962" name="Floating point hardware" superClass="fr.ac6.managedbuild.option.gnu.cross.fpu.715560000"/>
<option id="fr.ac6.managedbuild.option.gnu.cross.floatabi.224923540.1436221729" name="Floating-point ABI" superClass="fr.ac6.managedbuild.option.gnu.cross.floatabi.224923540"/>
- <tool id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.587456861" name="MCU GCC Compiler" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.83598944"/>
- <tool id="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.625175470" name="MCU G++ Compiler" superClass="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.1738856728"/>
+ <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="fr.ac6.managedbuild.targetPlatform.gnu.cross" isAbstract="false" osList="all" superClass="fr.ac6.managedbuild.targetPlatform.gnu.cross"/>
+ <tool id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.587456861" name="MCU GCC Compiler" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.83598944">
+ <inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c.1368851133" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.c"/>
+ <inputType id="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s.604279987" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.compiler.input.s"/>
+ </tool>
+ <tool id="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.625175470" name="MCU G++ Compiler" superClass="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.1738856728">
+ <inputType id="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.cpp.411311045" superClass="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.cpp"/>
+ <inputType id="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.s.970476416" superClass="fr.ac6.managedbuild.tool.gnu.cross.cpp.compiler.input.s"/>
+ </tool>
<tool id="fr.ac6.managedbuild.tool.gnu.cross.c.linker.617255926" name="MCU GCC Linker" superClass="fr.ac6.managedbuild.tool.gnu.cross.c.linker.433495544"/>
<tool id="fr.ac6.managedbuild.tool.gnu.cross.cpp.linker.855553111" name="MCU G++ Linker" superClass="fr.ac6.managedbuild.tool.gnu.cross.cpp.linker.584977711"/>
<tool id="fr.ac6.managedbuild.tool.gnu.archiver.2104881552" name="MCU GCC Archiver" superClass="fr.ac6.managedbuild.tool.gnu.archiver.925582677"/>
- <tool id="fr.ac6.managedbuild.tool.gnu.cross.assembler.699425738" name="MCU GCC Assembler" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler.1204646521"/>
+ <tool id="fr.ac6.managedbuild.tool.gnu.cross.assembler.699425738" name="MCU GCC Assembler" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler.1204646521">
+ <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1653386533" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+ <inputType id="fr.ac6.managedbuild.tool.gnu.cross.assembler.input.1494623861" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler.input"/>
+ </tool>
</toolChain>
</folderInfo>
<sourceEntries>
diff --git a/STM32F415APP/Application/Application.cpp b/STM32F415APP/Application/Application.cpp
index 5723d7c..420e0a4 100644
--- a/STM32F415APP/Application/Application.cpp
+++ b/STM32F415APP/Application/Application.cpp
@@ -32,7 +32,9 @@
#include "StHalIic.h"
#include "BoschBME280.h"
-//#include "Eeprom24.h"
+#include "Mlx90614.h"
+#include "Eeprom24.h"
+#include "Tcs34725.h"
// *****************************************************************************
// *** Get Instance ********************************************************
@@ -234,15 +236,16 @@ Result Application::IicPing(IIic& iic)
Result result = Result::ERR_I2C_UNKNOWN;
// Strings
- String str_arr[2+8+1];
+ String str_arr[2+8+2];
// Buffer for strings
- static char str_buf[8+1][64] = {0};
+ static char str_buf[8+2][64] = {0};
// Header
str_arr[8].SetParams(" | x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF", 0U, 0, COLOR_WHITE, String::FONT_6x8);
str_arr[9].SetParams("---------------------------------------------------", 0U, 8, COLOR_WHITE, String::FONT_6x8);
// Sensor data
str_arr[10U].SetParams(str_buf[8U], 0U, 8 * (2+10), COLOR_WHITE, String::FONT_8x12);
+ str_arr[11U].SetParams(str_buf[9U], 0U, 8 * (2+10) + 12, COLOR_WHITE, String::FONT_8x12);
// Show strings
for(uint32_t i = 0U; i < NumberOf(str_arr); i++)
{
@@ -255,18 +258,21 @@ Result Application::IicPing(IIic& iic)
str_arr[i].Show(10000);
}
- // TODO: test code below works, but by some reason break
- // BME280 communication. Use Logic Analyzer to figureout
- // what happens.
+// // EEPROM test code
// Eeprom24 eeprom(iic);
-// eeprom.Init();
+// result = eeprom.Init();
// uint8_t buf_out[] = "Test!!!";
-// result = eeprom.Write(0U, buf_out, sizeof(buf_out));
+// result |= eeprom.Write(0U, buf_out, sizeof(buf_out));
// uint8_t buf_in[16] = {0};
// result |= eeprom.Read(0U, buf_in, sizeof(buf_in));
+// RtosTick::DelayMs(1U);
// Sensor object
BoschBME280 bmp280(iic);
+ Mlx90614 mlx90614(iic);
+ Tcs34725 tcs34725(iic);
+ // Set error by default for initialize sensor first time
+ result = Result::ERR_I2C_UNKNOWN;
// Loop until user press "Left"
while(input_drv.GetButtonState(InputDrv::EXT_LEFT, InputDrv::BTN_LEFT) == false)
@@ -296,20 +302,97 @@ Result Application::IicPing(IIic& iic)
}
}
+ // Wait 50 ms - delay for Logic Analyzer
+ RtosTick::DelayMs(50U);
+
+ // *************************************************************************
+ // *** BME280 **********************************************************
+ // *************************************************************************
+
+// // Reinitialize sensor
+// if(result.IsBad())
+// {
+// result = bmp280.Initialize();
+// result |= bmp280.SetSampling(BoschBME280::MODE_FORCED);
+// }
+// // Take measurement
+// result |= bmp280.TakeMeasurement();
+// // Get values
+// int32_t temp = bmp280.GetTemperature_x100();
+// int32_t press = bmp280.GetPressure_x256() / 256;
+// int32_t humid = (bmp280.GetHumidity_x1024() * 100) / 1024;
+// // Generate string
+// sprintf(str_buf[8U], "T=%ld.%02ldC P=%ldPa H=%ld.%02ld%% %s", temp/100, abs(temp%100), press, humid/100, abs(humid%100), result.IsGood() ? "" : "ERROR"); // Received an ACK at that address
+
+ // *************************************************************************
+ // *** MLX90614 ********************************************************
+ // *************************************************************************
+
+// // Reinitialize sensor
+// if(result.IsBad())
+// {
+// result = mlx90614.Initialize();
+// }
+// int32_t temp_a = 0;
+// int32_t temp_o1 = 0;
+// int32_t temp_o2 = 0;
+// result = mlx90614.GetAmbientTemperature_x100(temp_a);
+// result |= mlx90614.GetObjectTemperature_x100(temp_o1);
+// result |= mlx90614.GetObjectTemperature_x100(temp_o2);
+// sprintf(str_buf[8U], "TA=%ld.%02ldC, TO1=%ld.%02ldC, TO2=%ld.%02ldC",
+// temp_a/100, abs(temp_a%100),
+// temp_o1/100, abs(temp_o1%100),
+// temp_o2/100, abs(temp_o2%100));
+
+ // *************************************************************************
+ // *** TCS34725 ********************************************************
+ // *************************************************************************
+
// Reinitialize sensor
if(result.IsBad())
{
- result = bmp280.Initialize();
- result |= bmp280.SetSampling(BoschBME280::MODE_FORCED);
+ result = tcs34725.Initialize();
}
- // Take measurement
- result |= bmp280.TakeMeasurement();
- // Get values
- int32_t temp = bmp280.GetTemperature_x100();
- int32_t press = bmp280.GetPressure_x256() / 256;
- int32_t humid = (bmp280.GetHumidity_x1024() * 100) / 1024;
- // Generate string
- sprintf(str_buf[8U], "T=%ld.%02ldC P=%ldPa H=%ld.%02ld%% %s", temp/100, abs(temp%100), press, humid/100, abs(humid%100), result.IsGood() ? "" : "ERROR"); // Received an ACK at that address
+
+ if(result.IsGood())
+ {
+ bool is_ready = false;
+ // Check data ready
+ result = tcs34725.IsDataReady(is_ready);
+ // If ready
+ if(result.IsGood() && is_ready)
+ {
+ uint16_t r, g, b, c;
+ result = tcs34725.GetRawData(r, g, b, c);
+ if(result.IsGood())
+ {
+ uint16_t lux;
+ uint16_t ct;
+ tcs34725.GetLux(lux);
+ tcs34725.GetColorTemperature(ct);
+ sprintf(str_buf[8U], "R=%5u, G=%5u, B=%5u, C=%5u", r, g, b, c);
+ sprintf(str_buf[9U], "L=%5u, CT=%5u", lux, ct);
+ // Check for low gain
+ if((uint32_t)c * tcs34725.GetGainValue() < 0xFFFFU)
+ {
+ result = tcs34725.IncGain();
+ }
+ // Check for max value
+ if(c == 0xFFFFU)
+ {
+ result = tcs34725.DecGain();
+ }
+ }
+ else
+ {
+ sprintf(str_buf[8U], "ERROR");
+ }
+ }
+ }
+
+ // *************************************************************************
+ // *** IicPing *********************************************************
+ // *************************************************************************
// Update display
display_drv.UpdateDisplay();
diff --git a/STM32F415APP/Application/Tetris.h b/STM32F415APP/Application/Tetris.h
index 8d1c9cf..b5f6d19 100644
--- a/STM32F415APP/Application/Tetris.h
+++ b/STM32F415APP/Application/Tetris.h
@@ -66,8 +66,6 @@ class Tetris : public AppTask
// Round flag
bool round = true;
- // Button states
- bool btn_states[InputDrv::BTN_MAX] = {false};
// Last left encoder value
int32_t last_enc1_val = 0;
// Last right encoder value
diff --git a/STM32F415APP/DevCore/DevCfg.h b/STM32F415APP/DevCore/DevCfg.h
index 3871b1b..6b15937 100644
--- a/STM32F415APP/DevCore/DevCfg.h
+++ b/STM32F415APP/DevCore/DevCfg.h
@@ -56,6 +56,7 @@
// Include for all hardware stuff
#include "main.h"
+#include "stm32f4xx.h"
// *** ADC *****************************************************************
#ifdef HAL_ADC_MODULE_ENABLED
@@ -81,6 +82,12 @@ typedef uint32_t I2C_HandleTypeDef; // Dummy I2C handle for compilation
#else
typedef uint32_t TIM_HandleTypeDef; // Dummy TIM handle for compilation
#endif
+// *** DAC *****************************************************************
+#ifdef HAL_DAC_MODULE_ENABLED
+#include "dac.h"
+#else
+typedef uint32_t DAC_HandleTypeDef; // Dummy DAC handle for compilation
+#endif
#include "usb_device.h"
diff --git a/STM32F415APP/DevCore/Display/DisplayDrv.cpp b/STM32F415APP/DevCore/Display/DisplayDrv.cpp
index 16c1eac..ac75415 100644
--- a/STM32F415APP/DevCore/Display/DisplayDrv.cpp
+++ b/STM32F415APP/DevCore/Display/DisplayDrv.cpp
@@ -42,12 +42,14 @@ Result DisplayDrv::Setup()
// If deisplay and touchscreen share same SPI
if(tft_hspi == touch_hspi)
{
- // Set prescaler for SPI
- MODIFY_REG(tft_hspi->Instance->CR1, (uint32_t)SPI_CR1_BR_Msk, SPI_BAUDRATEPRESCALER_64);
- // Init touchscreen driver
- touch.Init();
- // Restore prescaler for SPI
- MODIFY_REG(tft_hspi->Instance->CR1, (uint32_t)SPI_CR1_BR_Msk, SPI_BAUDRATEPRESCALER_2);
+ // Read original SPI prescaler
+ uint32_t prescaler = READ_REG(tft_hspi->Instance->CR1) & SPI_CR1_BR_Msk;
+ // Set prescaler for SPI
+ MODIFY_REG(tft_hspi->Instance->CR1, (uint32_t)SPI_CR1_BR_Msk, SPI_BAUDRATEPRESCALER_64);
+ // Init touchscreen driver
+ touch.Init();
+ // Restore prescaler for SPI
+ MODIFY_REG(tft_hspi->Instance->CR1, (uint32_t)SPI_CR1_BR_Msk, prescaler);
}
else
{
@@ -82,48 +84,50 @@ Result DisplayDrv::Loop()
if(screen_update.Take(100U) == Result::RESULT_OK)
{
// Set window for all screen and pointer to first pixel
- LockDisplay();
- // Set address window for all screen
- tft.SetAddrWindow(0, 0, width-1, height-1);
- // For each line/row
- for(int32_t i=0; i < height; i++)
+ if(LockDisplay() == Result::RESULT_OK)
{
- // Clear half of buffer
- memset(scr_buf[i%2], 0x00, sizeof(scr_buf[0]));
- // Take semaphore before draw line
- line_mutex.Lock();
- // Set pointer to first element
- VisObject* p_obj = object_list;
- // Do for all objects
- while(p_obj != nullptr)
+ // Set address window for all screen
+ tft.SetAddrWindow(0, 0, width-1, height-1);
+ // For each line/row
+ for(int32_t i=0; i < height; i++)
{
- // Draw object to buf
- if(update_mode) p_obj->DrawInBufH(scr_buf[i%2], width, i);
- else p_obj->DrawInBufW(scr_buf[i%2], width, i);
- // Set pointer to next object in list
- p_obj = p_obj->p_next;
+ // Clear half of buffer
+ memset(scr_buf[i%2], 0x00, sizeof(scr_buf[0]));
+ // Take semaphore before draw line
+ line_mutex.Lock();
+ // Set pointer to first element
+ VisObject* p_obj = object_list;
+ // Do for all objects
+ while(p_obj != nullptr)
+ {
+ // Draw object to buf
+ if(update_mode) p_obj->DrawInBufH(scr_buf[i%2], width, i);
+ else p_obj->DrawInBufW(scr_buf[i%2], width, i);
+ // Set pointer to next object in list
+ p_obj = p_obj->p_next;
+ }
+ // Give semaphore after changes
+ line_mutex.Release();
+ // Wait until previous transfer complete
+ while(tft.IsTransferComplete() == false) taskYIELD();
+ // Write stream to LCD
+ tft.SpiWriteStream((uint8_t*)scr_buf[i%2], width*tft.GetBytesPerPixel());
+ // DO NOT TRY "OPTIMIZE" CODE !!!
+ // Two "while" cycles used for generate next line when previous line
+ // transfer via SPI to display.
}
- // Give semaphore after changes
- line_mutex.Release();
- // Wait until previous transfer complete
+ // Wait until last transfer complete
while(tft.IsTransferComplete() == false) taskYIELD();
- // Write stream to LCD
- tft.SpiWriteStream((uint8_t*)scr_buf[i%2], width*tft.GetBytesPerPixel());
- // DO NOT TRY "OPTIMIZE" CODE !!!
- // Two "while" cycles used for generate next line when previous line
- // transfer via SPI to display.
- }
- // Wait until last transfer complete
- while(tft.IsTransferComplete() == false) taskYIELD();
- // Pull up CS
- tft.StopTransfer();
- // Give semaphore after draw frame
- UnlockDisplay();
- // Calculate FPS if debug info is ON
- if(DISPLAY_DEBUG_INFO)
- {
- // FPS in format XX.X
- fps_x10 = (1000 * 10) / (HAL_GetTick() - time_ms);
+ // Pull up CS
+ tft.StopTransfer();
+ // Give semaphore after draw frame
+ UnlockDisplay();
+ // Calculate FPS if debug info is ON
+ if(DISPLAY_DEBUG_INFO)
+ {
+ // FPS in format XX.X
+ fps_x10 = (1000 * 10) / (HAL_GetTick() - time_ms);
+ }
}
}
diff --git a/STM32F415APP/DevCore/Display/Image.cpp b/STM32F415APP/DevCore/Display/Image.cpp
index cc17e54..36c3fb5 100644
--- a/STM32F415APP/DevCore/Display/Image.cpp
+++ b/STM32F415APP/DevCore/Display/Image.cpp
@@ -29,7 +29,7 @@
// *****************************************************************************
// *** Constructor *********************************************************
// *****************************************************************************
-Image::Image(int32_t x, int32_t y, const ImageDesc& img_dsc) : img_description(img_dsc)
+Image::Image(int32_t x, int32_t y, const ImageDesc& img_dsc)
{
x_start = x;
y_start = y;
diff --git a/STM32F415APP/DevCore/Display/Image.h b/STM32F415APP/DevCore/Display/Image.h
index 57061bd..67d4ab5 100644
--- a/STM32F415APP/DevCore/Display/Image.h
+++ b/STM32F415APP/DevCore/Display/Image.h
@@ -84,13 +84,18 @@ class Image : public VisObject
// *************************************************************************
// *** Constructor *****************************************************
// *************************************************************************
+ Image() {};
+
+ // *************************************************************************
+ // *** Constructor *****************************************************
+ // *************************************************************************
Image(int32_t x, int32_t y, const ImageDesc& img_dsc);
// *************************************************************************
// *** Put line in buffer **********************************************
// *************************************************************************
virtual void DrawInBufH(uint16_t* buf, int32_t n, int32_t row, int32_t y = 0);
-
+
// *************************************************************************
// *** Put line in buffer **********************************************
// *************************************************************************
@@ -100,25 +105,23 @@ class Image : public VisObject
// *** Set Horizontal Flip function ************************************
// *************************************************************************
void SetHorizontalFlip(bool flip) {hor_mirror = flip;}
-
+
// *************************************************************************
// *** Set Image function **********************************************
// *************************************************************************
void SetImage(const ImageDesc& img_dsc, bool semaphore_taken = false);
protected:
- // Reference to image description structure
- const ImageDesc& img_description;
// Bits per pixel
- uint8_t bits_per_pixel;
+ uint8_t bits_per_pixel = 0U;
// Pointer to the image
- const void* img;
+ const void* img = nullptr;
// Pointer to the palette
- const uint16_t* palette;
+ const uint16_t* palette = nullptr;
// Transparent color (-1 no transparent colors)
- int32_t transparent_color;
+ int32_t transparent_color = -1;
// Horizontal mirror
- bool hor_mirror;
+ bool hor_mirror = false;
};
// *****************************************************************************
diff --git a/STM32F415APP/DevCore/Display/Primitives.cpp b/STM32F415APP/DevCore/Display/Primitives.cpp
index 2b7ad57..85ad546 100644
--- a/STM32F415APP/DevCore/Display/Primitives.cpp
+++ b/STM32F415APP/DevCore/Display/Primitives.cpp
@@ -31,7 +31,7 @@
// *****************************************************************************
// *** Constructor *********************************************************
// *****************************************************************************
-Box::Box(int32_t x, int32_t y, int32_t w, int32_t h, int32_t c, bool is_fill)
+Box::Box(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t c, bool is_fill)
{
SetParams(x, y, w, h, c, is_fill);
}
@@ -39,7 +39,7 @@ Box::Box(int32_t x, int32_t y, int32_t w, int32_t h, int32_t c, bool is_fill)
// *****************************************************************************
// *** SetParams ***********************************************************
// *****************************************************************************
-void Box::SetParams(int32_t x, int32_t y, int32_t w, int32_t h, int32_t c, bool is_fill)
+void Box::SetParams(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t c, bool is_fill)
{
color = c;
x_start = x;
diff --git a/STM32F415APP/DevCore/Display/Primitives.h b/STM32F415APP/DevCore/Display/Primitives.h
index 2a4e0ee..408c454 100644
--- a/STM32F415APP/DevCore/Display/Primitives.h
+++ b/STM32F415APP/DevCore/Display/Primitives.h
@@ -58,12 +58,12 @@ class Box : public VisObject
// *************************************************************************
// *** Constructor *****************************************************
// *************************************************************************
- Box(int32_t x, int32_t y, int32_t w, int32_t h, int32_t c, bool is_fill = false);
+ Box(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t c, bool is_fill = false);
// *************************************************************************
// *** SetParams *******************************************************
// *************************************************************************
- void SetParams(int32_t x, int32_t y, int32_t w, int32_t h, int32_t c, bool is_fill = false);
+ void SetParams(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t c, bool is_fill = false);
// *************************************************************************
// *** Put line in buffer **********************************************
diff --git a/STM32F415APP/DevCore/Drivers/StHalIic.cpp b/STM32F415APP/DevCore/Drivers/StHalIic.cpp
index 2f231a1..49d648e 100644
--- a/STM32F415APP/DevCore/Drivers/StHalIic.cpp
+++ b/STM32F415APP/DevCore/Drivers/StHalIic.cpp
@@ -87,21 +87,40 @@ Result StHalIic::Transfer(uint16_t addr, uint8_t* tx_buf_ptr, uint32_t tx_size,
{
Result result = Result::ERR_NULL_PTR;
- if(tx_buf_ptr != nullptr)
+ // Special hack for use HAL_I2C_Mem_Read() function for send Repeated Start if
+ // tx_size is 1 or 2 bytes.
+ if((tx_buf_ptr != nullptr) && (rx_buf_ptr != nullptr) && ((tx_size == 1U) || (tx_size == 2U)))
{
+ // Variable for store result from the HAL
+ HAL_StatusTypeDef hal_result = HAL_OK;
+
+ // Shift address one bit left - HAL blow away LSB, not MSB.
+ addr <<= 1U;
+
// Transmit data
- result = Write(addr, tx_buf_ptr, tx_size);
- }
+ hal_result = HAL_I2C_Mem_Read(&hi2c, addr, tx_buf_ptr[0], tx_size, rx_buf_ptr, rx_size, i2c_tx_timeout_ms);
- if((rx_buf_ptr != nullptr) && result.IsGood())
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+ else
{
- // Clear RX buffer
- for(uint32_t i = 0; i < rx_size; i++)
+ if(tx_buf_ptr != nullptr)
+ {
+ // Transmit data
+ result = Write(addr, tx_buf_ptr, tx_size);
+ }
+
+ if((rx_buf_ptr != nullptr) && result.IsGood())
{
- rx_buf_ptr[i] = 0;
+ // Clear RX buffer
+ for(uint32_t i = 0; i < rx_size; i++)
+ {
+ rx_buf_ptr[i] = 0;
+ }
+ // Receive data
+ result = Read(addr, rx_buf_ptr, rx_size);
}
- // Receive data
- result = Read(addr, rx_buf_ptr, rx_size);
}
return result;
diff --git a/STM32F415APP/DevCore/Drivers/StHalSpi.cpp b/STM32F415APP/DevCore/Drivers/StHalSpi.cpp
new file mode 100644
index 0000000..19f1865
--- /dev/null
+++ b/STM32F415APP/DevCore/Drivers/StHalSpi.cpp
@@ -0,0 +1,335 @@
+//******************************************************************************
+// @file StHalIic.cpp
+// @author Nicolai Shlapunov
+//
+// @details DevCore: STM32 HAL SPI driver, implementation
+//
+// @copyright Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "StHalSpi.h"
+
+// *****************************************************************************
+// *** This driver can be compiled only if SPI configured in CubeMX ********
+// *****************************************************************************
+#ifdef HAL_SPI_MODULE_ENABLED
+
+// *****************************************************************************
+// *** Public: Transfer ****************************************************
+// *****************************************************************************
+Result StHalSpi::Transfer(uint8_t* rx_buf_ptr, uint8_t* tx_buf_ptr, uint32_t size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ // Check for null pointer
+ if((rx_buf_ptr != nullptr) && (tx_buf_ptr != nullptr))
+ {
+ // Read data from SPI port
+ HAL_StatusTypeDef hal_result = HAL_SPI_TransmitReceive(&hspi, tx_buf_ptr, rx_buf_ptr, size, spi_tx_timeout_ms);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Write *******************************************************
+// *****************************************************************************
+Result StHalSpi::Write(uint8_t* tx_buf_ptr, uint32_t size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ // Check for null pointer
+ if (tx_buf_ptr != nullptr)
+ {
+ // Read data from SPI port
+ HAL_StatusTypeDef hal_result = HAL_SPI_Transmit(&hspi, tx_buf_ptr, size, spi_tx_timeout_ms);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Read ********************************************************
+// *****************************************************************************
+Result StHalSpi::Read(uint8_t* rx_buf_ptr, uint32_t size)
+{
+ Result result = Result::RESULT_OK;
+
+ // Check for null pointer
+ if (rx_buf_ptr != nullptr)
+ {
+ // Read data from the SPI port
+ HAL_StatusTypeDef hal_result = HAL_SPI_Receive(&hspi, rx_buf_ptr, size, spi_rx_timeout_ms);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: TransferAsync ***********************************************
+// *****************************************************************************
+Result StHalSpi::TransferAsync(uint8_t* rx_buf_ptr, uint8_t* tx_buf_ptr, uint32_t size)
+{
+ Result result = Result::RESULT_OK;
+
+ // Check for null pointer
+ if((rx_buf_ptr != nullptr) && (tx_buf_ptr != nullptr))
+ {
+ // Read data from SPI port
+ HAL_StatusTypeDef hal_result = HAL_SPI_TransmitReceive_DMA(&hspi, tx_buf_ptr, rx_buf_ptr, size);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: WriteAsync **************************************************
+// *****************************************************************************
+Result StHalSpi::WriteAsync(uint8_t* tx_buf_ptr, uint32_t size)
+{
+ Result result = Result::RESULT_OK;
+
+ // Check for null pointer
+ if(tx_buf_ptr != nullptr)
+ {
+ // Read data from SPI port
+ HAL_StatusTypeDef hal_result = HAL_SPI_Transmit_DMA(&hspi, tx_buf_ptr, size);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: ReadAsync ***************************************************
+// *****************************************************************************
+Result StHalSpi::ReadAsync(uint8_t* rx_buf_ptr, uint32_t size)
+{
+ Result result = Result::RESULT_OK;
+
+ // Check for null pointer
+ if(rx_buf_ptr != nullptr)
+ {
+ // Read data from SPI port
+ HAL_StatusTypeDef hal_result = HAL_SPI_Receive_DMA(&hspi, rx_buf_ptr, size);
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Check SPI transfer status ***********************************
+// *****************************************************************************
+bool StHalSpi::IsTransferComplete(void)
+{
+ return(hspi.State != HAL_SPI_STATE_BUSY_TX);
+}
+
+// *****************************************************************************
+// *** Public: Abort *******************************************************
+// *****************************************************************************
+Result StHalSpi::Abort(void)
+{
+ Result result = Result::RESULT_OK;
+
+ // Abort SPI transmissions data from SPI port
+ HAL_StatusTypeDef hal_result = HAL_SPI_Abort(&hspi); // TODO: what difference from HAL_SPI_Abort_IT(&hspi) ???
+ // Convert operation result to Result
+ result = ConvertResult(hal_result);
+
+ return result;
+}
+
+// *************************************************************************
+// *** Public: SetSpeed ************************************************
+// *************************************************************************
+Result StHalSpi::SetSpeed(uint32_t clock_rate)
+{
+ Result result = Result::RESULT_OK;
+
+ // Get SPI bus clock
+ uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
+ // Find divider
+ uint32_t divider = pclk2 / clock_rate;
+ // Variable for baud prescaler
+ uint32_t baud_prescaler = SPI_BAUDRATEPRESCALER_2;
+
+ // Set prescaler for SPI
+ if(divider <= 2U)
+ {
+ baud_prescaler = SPI_BAUDRATEPRESCALER_2;
+ clock_rate = pclk2 * 2U;
+ }
+ else if(divider <= 4U)
+ {
+ baud_prescaler = SPI_BAUDRATEPRESCALER_4;
+ clock_rate = pclk2 * 4U;
+ }
+ else if(divider <= 8U)
+ {
+ baud_prescaler = SPI_BAUDRATEPRESCALER_8;
+ clock_rate = pclk2 * 8U;
+ }
+ else if(divider <= 16U)
+ {
+ baud_prescaler = SPI_BAUDRATEPRESCALER_16;
+ clock_rate = pclk2 * 16U;
+ }
+ else if(divider <= 32U)
+ {
+ baud_prescaler = SPI_BAUDRATEPRESCALER_32;
+ clock_rate = pclk2 * 32U;
+ }
+ else if(divider <= 64U)
+ {
+ baud_prescaler = SPI_BAUDRATEPRESCALER_64;
+ clock_rate = pclk2 * 64U;
+ }
+ else if(divider <= 128U)
+ {
+ baud_prescaler = SPI_BAUDRATEPRESCALER_128;
+ clock_rate = pclk2 * 128U;
+ }
+ else if(divider <= 256U)
+ {
+ baud_prescaler = SPI_BAUDRATEPRESCALER_256;
+ clock_rate = pclk2 * 256U;
+ }
+ else
+ {
+ // We can't set requested or lower speed
+ result = Result::ERR_SPI_GENERAL;
+ }
+
+ if(result.IsGood())
+ {
+ // Set prescaler
+ MODIFY_REG(hspi.Instance->CR1, (uint32_t)SPI_CR1_BR_Msk, baud_prescaler);
+ }
+
+ return result;
+}
+
+// *************************************************************************
+// *** Public: GetSpeed ************************************************
+// *************************************************************************
+Result StHalSpi::GetSpeed(uint32_t& clock_rate)
+{
+ Result result = Result::RESULT_OK;
+
+ // Get SPI bus clock
+ uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
+ // Get prescaler
+ uint32_t baud_prescaler = READ_REG(hspi.Instance->CR1) & (uint32_t)SPI_CR1_BR_Msk;
+
+ // Set prescaler for SPI
+ if(baud_prescaler == SPI_BAUDRATEPRESCALER_2)
+ {
+ clock_rate = pclk2 * 2U;
+ }
+ else if(baud_prescaler == SPI_BAUDRATEPRESCALER_4)
+ {
+ clock_rate = pclk2 * 4U;
+ }
+ else if(baud_prescaler == SPI_BAUDRATEPRESCALER_8)
+ {
+ clock_rate = pclk2 * 8U;
+ }
+ else if(baud_prescaler == SPI_BAUDRATEPRESCALER_16)
+ {
+ clock_rate = pclk2 * 16U;
+ }
+ else if(baud_prescaler == SPI_BAUDRATEPRESCALER_32)
+ {
+ clock_rate = pclk2 * 32U;
+ }
+ else if(baud_prescaler == SPI_BAUDRATEPRESCALER_64)
+ {
+ clock_rate = pclk2 * 64U;
+ }
+ else if(baud_prescaler == SPI_BAUDRATEPRESCALER_128)
+ {
+ clock_rate = pclk2 * 128U;
+ }
+ else if(baud_prescaler == SPI_BAUDRATEPRESCALER_256)
+ {
+ clock_rate = pclk2 * 256U;
+ }
+ else
+ {
+ // Clear result clock rate
+ clock_rate = 0U;
+ // We shouldn't get here
+ result = Result::ERR_SPI_GENERAL;
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Private: GetToDataSizeBytes *****************************************
+// *****************************************************************************
+uint32_t StHalSpi::GetToDataSizeBytes()
+{
+ // Shift by a byte and add one because 0x300 is 4 bits
+ return(hspi.Init.DataSize >> 8U) + 1U;
+}
+
+// *****************************************************************************
+// *** Private: ConvertResult **********************************************
+// *****************************************************************************
+Result StHalSpi::ConvertResult(HAL_StatusTypeDef hal_result)
+{
+ Result result = Result::RESULT_OK;
+
+ // Convert operation result to Result
+ switch(hal_result)
+ {
+ case HAL_OK:
+ result = Result::RESULT_OK;
+ break;
+
+ case HAL_ERROR:
+ result = Result::ERR_SPI_GENERAL;
+ break;
+
+ case HAL_BUSY:
+ result = Result::ERR_SPI_BUSY;
+ break;
+
+ case HAL_TIMEOUT:
+ result = Result::ERR_SPI_TIMEOUT;
+ break;
+
+ default:
+ result = Result::ERR_SPI_UNKNOWN;
+ break;
+ }
+
+ // Return result
+ return result;
+}
+
+#endif
diff --git a/STM32F415APP/DevCore/Drivers/StHalSpi.h b/STM32F415APP/DevCore/Drivers/StHalSpi.h
new file mode 100644
index 0000000..2681f19
--- /dev/null
+++ b/STM32F415APP/DevCore/Drivers/StHalSpi.h
@@ -0,0 +1,162 @@
+//******************************************************************************
+// @file StHalSpi.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: STM32 HAL SPI driver, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef StmHalSpi_h
+#define StmHalSpi_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+#include "ISpi.h"
+
+// *****************************************************************************
+// *** This driver can be compiled only if UART configured in CubeMX *******
+// *****************************************************************************
+#ifndef HAL_SPI_MODULE_ENABLED
+ typedef uint32_t SPI_HandleTypeDef; // Dummy SPI handle for header compilation
+#endif
+
+// *****************************************************************************
+// *** STM32 HAL ISPI Driver Class ****************************************
+// *****************************************************************************
+class StHalSpi : public ISpi
+{
+ public:
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ explicit StHalSpi(SPI_HandleTypeDef& hspi_ref) : hspi(hspi_ref) {};
+
+ // *************************************************************************
+ // *** Public: Destructor **********************************************
+ // *************************************************************************
+ ~StHalSpi() {};
+
+ // *************************************************************************
+ // *** Public: Init ****************************************************
+ // *************************************************************************
+ virtual Result Init() {return Result::RESULT_OK;}
+
+ // *************************************************************************
+ // *** Public: DeInit **************************************************
+ // *************************************************************************
+ virtual Result DeInit() {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Transfer ************************************************
+ // *************************************************************************
+ virtual Result Transfer(uint8_t* rx_buf_ptr, uint8_t* tx_buf_ptr, uint32_t size);
+
+ // *************************************************************************
+ // *** Public: Write ***************************************************
+ // *************************************************************************
+ virtual Result Write(uint8_t* tx_buf_ptr, uint32_t tx_size);
+
+ // *************************************************************************
+ // *** Public: Read ****************************************************
+ // *************************************************************************
+ virtual Result Read(uint8_t* rx_buf_ptr, uint32_t rx_size);
+
+ // *************************************************************************
+ // *** Public: TransferAsync *******************************************
+ // *************************************************************************
+ virtual Result TransferAsync(uint8_t* rx_buf_ptr, uint8_t* tx_buf_ptr, uint32_t size);
+
+ // *************************************************************************
+ // *** Public: WriteAsync **********************************************
+ // *************************************************************************
+ virtual Result WriteAsync(uint8_t* tx_buf_ptr, uint32_t tx_size);
+
+ // *************************************************************************
+ // *** Public: ReadAsync ***********************************************
+ // *************************************************************************
+ virtual Result ReadAsync(uint8_t* rx_buf_ptr, uint32_t rx_size);
+
+ // *************************************************************************
+ // *** Public: Check SPI transfer status *******************************
+ // *************************************************************************
+ virtual bool IsTransferComplete(void);
+
+ // *************************************************************************
+ // *** Public: Abort ***************************************************
+ // *************************************************************************
+ virtual Result Abort(void);
+
+ // *************************************************************************
+ // *** Public: SetSpeed ************************************************
+ // *************************************************************************
+ virtual Result SetSpeed(uint32_t clock_rate);
+
+ // *************************************************************************
+ // *** Public: GetSpeed ************************************************
+ // *************************************************************************
+ virtual Result GetSpeed(uint32_t& clock_rate);
+
+ private:
+ // Reference to the SPI handle
+ SPI_HandleTypeDef& hspi;
+
+ // *************************************************************************
+ // *** Private: GetToDataSizeBytes *************************************
+ // *************************************************************************
+ uint32_t GetToDataSizeBytes();
+
+ // *************************************************************************
+ // *** Private: ConvertResult ******************************************
+ // *************************************************************************
+ Result ConvertResult(HAL_StatusTypeDef hal_result);
+
+ // *************************************************************************
+ // *** Private: Constructors and assign operator - prevent copying *****
+ // *************************************************************************
+ StHalSpi();
+ StHalSpi(const StHalSpi&);
+ StHalSpi& operator=(const StHalSpi);
+};
+
+#endif
diff --git a/STM32F415APP/DevCore/Drivers/StHalUart.cpp b/STM32F415APP/DevCore/Drivers/StHalUart.cpp
new file mode 100644
index 0000000..e9b261a
--- /dev/null
+++ b/STM32F415APP/DevCore/Drivers/StHalUart.cpp
@@ -0,0 +1,202 @@
+//******************************************************************************
+// @file StHalUart.cpp
+// @author Nicolai Shlapunov
+//
+// @details DevCore: STM32 HAL UART driver, implementation
+//
+// @copyright Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "StHalUart.h"
+
+// *****************************************************************************
+// *** This driver can be compiled only if UART configured in CubeMX *******
+// *****************************************************************************
+#ifdef HAL_USART_MODULE_ENABLED
+
+// *****************************************************************************
+// *** Public: Init ********************************************************
+// *****************************************************************************
+Result StHalUart::Init()
+{
+ Result result = Result::RESULT_OK;
+
+ // Clear array
+ memset(rx_buf, 0xFFU, sizeof(rx_buf));
+
+ // Start the RX DMA - this is circular, so it will never stop
+ if(HAL_UART_Receive_DMA(&huart, rx_buf, RX_BUF_SIZE) == HAL_OK)
+ {
+ // This is the first access to this object and ndtr must be initialized
+ ndtr = huart.RxXferSize;
+ }
+ else
+ {
+ result = Result::ERR_UART_RECEIVE;
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: DeInit ******************************************************
+// *****************************************************************************
+Result StHalUart::DeInit()
+{
+ Result result = Result::RESULT_OK;
+
+ if(HAL_UART_Abort(&huart) != HAL_OK)
+ {
+ result = Result::ERR_UART_GENERAL;
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Read ********************************************************
+// *****************************************************************************
+Result StHalUart::Read(uint8_t* rx_buf_ptr, uint32_t& size)
+{
+ Result result = Result::RESULT_OK;
+
+ uint16_t rx_idx = 0U;
+ // Read bytes in cycle
+ while(rx_idx < size)
+ {
+ // Temporary variable for received byte
+ uint8_t rx_byte;
+ // Read byte - this function overwrite byte in case of overrun. So,
+ // we use additional variable here. May be it isn't so necessary.
+ result = Pop(rx_byte);
+ // If read successful
+ if(result.IsGood())
+ {
+ // Save received byte
+ rx_buf_ptr[rx_idx] = rx_byte;
+ // Increment index
+ rx_idx++;
+ }
+ else
+ {
+ // Exit from the cycle
+ break;
+ }
+ }
+ // Save read bytes count
+ size = rx_idx;
+ // If we received any number of bytes - override "empty" error
+ if((rx_idx != 0U) && (result == Result::ERR_UART_EMPTY))
+ {
+ result = Result::RESULT_OK;
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Write *******************************************************
+// *****************************************************************************
+Result StHalUart::Write(uint8_t* tx_buf_ptr, uint32_t size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ // Check input parameters
+ if(tx_buf_ptr != nullptr)
+ {
+ // Transfer data
+ HAL_StatusTypeDef hal_result = HAL_UART_Transmit_DMA(&huart, tx_buf_ptr, size);
+
+ // Convert operation result to Result
+ if(hal_result == HAL_BUSY)
+ {
+ // Busy error
+ result = Result::ERR_UART_BUSY;
+ }
+ else if(hal_result != HAL_OK)
+ {
+ // All other errors
+ result = Result::ERR_UART_TRANSMIT;
+ }
+ else
+ {
+ result = Result::RESULT_OK;
+ }
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: IsTxComplete ************************************************
+// *****************************************************************************
+bool StHalUart::IsTxComplete(void)
+{
+ // Check gState
+ return (huart.gState == HAL_UART_STATE_READY);
+}
+
+// *****************************************************************************
+// *** Private: GetRxSize **************************************************
+// *****************************************************************************
+Result StHalUart::GetRxSize(uint16_t& rx_cnt)
+{
+ // Get DMA counter from register
+ uint16_t new_ndtr = __HAL_DMA_GET_COUNTER(huart.hdmarx);
+ // Calculate number of received bytes
+ if(ndtr >= new_ndtr)
+ {
+ rx_cnt = ndtr - new_ndtr;
+ }
+ else
+ {
+ rx_cnt = huart.RxXferSize - (new_ndtr - ndtr);
+ }
+
+ return Result::RESULT_OK;
+}
+
+// *****************************************************************************
+// *** Private: Pop ********************************************************
+// *****************************************************************************
+Result StHalUart::Pop(uint8_t& value)
+{
+ Result result = Result::RESULT_OK;
+
+ // Calculate index in circular buffer
+ uint16_t index = RX_BUF_SIZE - ndtr;
+
+ // Check data
+ if(ndtr != __HAL_DMA_GET_COUNTER(huart.hdmarx))
+ {
+ // Store value
+ value = rx_buf[index];
+ // Decrease counter
+ ndtr--;
+ // Check reset
+ if(ndtr == 0U)
+ {
+ ndtr = RX_BUF_SIZE;
+ }
+ }
+ else
+ {
+ // No data
+ result = Result::ERR_UART_EMPTY;
+ }
+
+ return result;
+}
+
+#endif
diff --git a/STM32F415APP/DevCore/Drivers/StHalUart.h b/STM32F415APP/DevCore/Drivers/StHalUart.h
new file mode 100644
index 0000000..0864c24
--- /dev/null
+++ b/STM32F415APP/DevCore/Drivers/StHalUart.h
@@ -0,0 +1,131 @@
+//******************************************************************************
+// @file StHalUart.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: STM32 HAL UART driver, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef StHalUart_h
+#define StHalUart_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+#include "IUart.h"
+
+// *****************************************************************************
+// *** This driver can be compiled only if UART configured in CubeMX *******
+// *****************************************************************************
+#ifndef HAL_USART_MODULE_ENABLED
+ typedef uint32_t UART_HandleTypeDef; // Dummy UART handle for header compilation
+#endif
+
+// *****************************************************************************
+// *** STM32 HAL UART Driver Class *****************************************
+// *****************************************************************************
+class StHalUart : public IUart
+{
+ public:
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ explicit StHalUart(UART_HandleTypeDef& huart_ref) : huart(huart_ref) {};
+
+ // *************************************************************************
+ // *** Public: Init ****************************************************
+ // *************************************************************************
+ Result Init();
+
+ // *************************************************************************
+ // *** Public: DeInit **************************************************
+ // *************************************************************************
+ Result DeInit();
+
+ // *************************************************************************
+ // *** Public: Read ****************************************************
+ // *************************************************************************
+ Result Read(uint8_t* rx_buf_ptr, uint32_t& size);
+
+ // *************************************************************************
+ // *** Public: Write ***************************************************
+ // *************************************************************************
+ Result Write(uint8_t* tx_buf_ptr, uint32_t size);
+
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ bool IsTxComplete(void);
+
+ private:
+ // Size of buffer for receive data
+ static const uint16_t RX_BUF_SIZE = 128U;
+
+ // Buffer for receive data
+ uint8_t rx_buf[RX_BUF_SIZE];
+
+ // Reference to the UART handle
+ UART_HandleTypeDef& huart;
+
+ // Offset into DMA receive buffer of next character to receive
+ uint16_t ndtr = 0U;
+
+ // *************************************************************************
+ // *** Private: GetRxSize **********************************************
+ // *************************************************************************
+ Result GetRxSize(uint16_t& rx_cnt);
+
+ // *************************************************************************
+ // *** Private: Pop ****************************************************
+ // *************************************************************************
+ Result Pop(uint8_t& value);
+
+ // *************************************************************************
+ // *** Private: Constructors and assign operator - prevent copying *****
+ // *************************************************************************
+ StHalUart();
+ StHalUart(const StHalUart&);
+ StHalUart& operator=(const StHalUart);
+};
+
+#endif
diff --git a/STM32F415APP/DevCore/FreeRtosWrapper/Rtos.cpp b/STM32F415APP/DevCore/FreeRtosWrapper/Rtos.cpp
index 549df51..1775508 100644
--- a/STM32F415APP/DevCore/FreeRtosWrapper/Rtos.cpp
+++ b/STM32F415APP/DevCore/FreeRtosWrapper/Rtos.cpp
@@ -62,7 +62,7 @@ bool Rtos::IsInHandlerMode(void)
// *****************************************************************************
void Rtos::SuspendScheduler()
{
- vTaskSuspendAll();
+ vTaskSuspendAll();
}
// *****************************************************************************
@@ -70,9 +70,7 @@ void Rtos::SuspendScheduler()
// *****************************************************************************
void Rtos::ResumeScheduler()
{
- // Discard return value, since the destructor can't do anything with it
- // and it's unlikely to be used.
- (void) xTaskResumeAll();
+ (void) xTaskResumeAll();
}
// *****************************************************************************
@@ -80,7 +78,7 @@ void Rtos::ResumeScheduler()
// *****************************************************************************
void Rtos::EnterCriticalSection()
{
- taskENTER_CRITICAL();
+ taskENTER_CRITICAL();
}
// *****************************************************************************
@@ -88,7 +86,7 @@ void Rtos::EnterCriticalSection()
// *****************************************************************************
void Rtos::ExitCriticalSection()
{
- taskEXIT_CRITICAL();
+ taskEXIT_CRITICAL();
}
// *****************************************************************************
@@ -96,7 +94,7 @@ void Rtos::ExitCriticalSection()
// *****************************************************************************
void Rtos::DisableInterrupts()
{
- taskDISABLE_INTERRUPTS();
+ taskDISABLE_INTERRUPTS();
}
// *****************************************************************************
@@ -104,5 +102,5 @@ void Rtos::DisableInterrupts()
// *****************************************************************************
void Rtos::EnableInterrupts()
{
- taskENABLE_INTERRUPTS();
+ taskENABLE_INTERRUPTS();
}
diff --git a/STM32F415APP/DevCore/Interfaces/ISpi.h b/STM32F415APP/DevCore/Interfaces/ISpi.h
new file mode 100644
index 0000000..1803354
--- /dev/null
+++ b/STM32F415APP/DevCore/Interfaces/ISpi.h
@@ -0,0 +1,156 @@
+//******************************************************************************
+// @file ISpi.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: SPI driver interface, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef ISpi_h
+#define ISpi_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+
+// *****************************************************************************
+// *** SPI Driver Interface ************************************************
+// *****************************************************************************
+class ISpi
+{
+ public:
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ explicit ISpi() {};
+
+ // *************************************************************************
+ // *** Public: Destructor **********************************************
+ // *************************************************************************
+ virtual ~ISpi() {};
+
+ // *************************************************************************
+ // *** Public: Init ****************************************************
+ // *************************************************************************
+ virtual Result Init() = 0;
+
+ // *************************************************************************
+ // *** Public: DeInit **************************************************
+ // *************************************************************************
+ virtual Result DeInit() {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Transfer ************************************************
+ // *************************************************************************
+ virtual Result Transfer(uint8_t* rx_buf_ptr, uint8_t* tx_buf_ptr, uint32_t size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Write ***************************************************
+ // *************************************************************************
+ virtual Result Write(uint8_t* tx_buf_ptr, uint32_t tx_size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Read ****************************************************
+ // *************************************************************************
+ virtual Result Read(uint8_t* rx_buf_ptr, uint32_t rx_size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: TransferAsync *******************************************
+ // *************************************************************************
+ virtual Result TransferAsync(uint8_t* rx_buf_ptr, uint8_t* tx_buf_ptr, uint32_t size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: WriteAsync **********************************************
+ // *************************************************************************
+ virtual Result WriteAsync(uint8_t* tx_buf_ptr, uint32_t tx_size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: ReadAsync ***********************************************
+ // *************************************************************************
+ virtual Result ReadAsync(uint8_t* rx_buf_ptr, uint32_t rx_size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Check SPI transfer status *******************************
+ // *************************************************************************
+ virtual bool IsTransferComplete(void) {return true;}
+
+ // *************************************************************************
+ // *** Public: Abort ***************************************************
+ // *************************************************************************
+ virtual Result Abort(void) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: SetSpeed ************************************************
+ // *************************************************************************
+ virtual Result SetSpeed(uint32_t clock_rate) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: GetSpeed ************************************************
+ // *************************************************************************
+ virtual Result GetSpeed(uint32_t& clock_rate) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: SetTxTimeout ********************************************
+ // *************************************************************************
+ virtual void SetTxTimeout(uint16_t timeout_ms) {spi_tx_timeout_ms = timeout_ms;}
+
+ // *************************************************************************
+ // *** Public: SetRxTimeout ********************************************
+ // *************************************************************************
+ virtual void SetRxTimeout(uint16_t timeout_ms) {spi_rx_timeout_ms = timeout_ms;}
+
+ protected:
+ // Timeout for SPI TX operation
+ uint16_t spi_tx_timeout_ms = 100U;
+
+ // Timeout for SPI RX operation
+ uint16_t spi_rx_timeout_ms = 100U;
+
+ private:
+ // *************************************************************************
+ // *** Private: Constructors and assign operator - prevent copying *****
+ // *************************************************************************
+ ISpi(const ISpi&);
+};
+
+#endif
diff --git a/STM32F415APP/DevCore/Interfaces/IUart.h b/STM32F415APP/DevCore/Interfaces/IUart.h
new file mode 100644
index 0000000..83fa3b1
--- /dev/null
+++ b/STM32F415APP/DevCore/Interfaces/IUart.h
@@ -0,0 +1,104 @@
+//******************************************************************************
+// @file IUart.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: UART driver interface, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef IUart_h
+#define IUart_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+
+// *****************************************************************************
+// *** UART Driver Interface ***********************************************
+// *****************************************************************************
+class IUart
+{
+ public:
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ explicit IUart() {};
+
+ // *************************************************************************
+ // *** Public: Destructor **********************************************
+ // *************************************************************************
+ virtual ~IUart() {};
+
+ // *************************************************************************
+ // *** Public: Init ****************************************************
+ // *************************************************************************
+ virtual Result Init() = 0;
+
+ // *************************************************************************
+ // *** Public: DeInit **************************************************
+ // *************************************************************************
+ virtual Result DeInit() {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Read ****************************************************
+ // *************************************************************************
+ virtual Result Read(uint8_t* rx_buf_ptr, uint32_t& size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Write ***************************************************
+ // *************************************************************************
+ virtual Result Write(uint8_t* tx_buf_ptr, uint32_t size) {return Result::ERR_NOT_IMPLEMENTED;}
+
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ virtual bool IsTxComplete(void) {return true;}
+
+ private:
+ // *************************************************************************
+ // *** Private: Constructors and assign operator - prevent copying *****
+ // *************************************************************************
+ IUart(const IUart&);
+};
+
+#endif
diff --git a/STM32F415APP/DevCore/Libraries/BoschBME280.cpp b/STM32F415APP/DevCore/Libraries/BoschBME280.cpp
index 27029ed..d085e4b 100644
--- a/STM32F415APP/DevCore/Libraries/BoschBME280.cpp
+++ b/STM32F415APP/DevCore/Libraries/BoschBME280.cpp
@@ -23,10 +23,13 @@
// *****************************************************************************
// *** Initialize **********************************************************
// *****************************************************************************
-Result BoschBME280::Initialize()
+Result BoschBME280::Initialize(uint8_t addr)
{
Result result = Result::RESULT_OK;
+ // Save I2C sensor address
+ i2c_addr = addr;
+
result = iic.Enable();
if(result.IsGood())
@@ -104,7 +107,7 @@ Result BoschBME280::SetSampling(SensorModeType mode,
// otherwise the values will not be applied (see datasheet 5.4.3)
ctrl_hum_reg.reserved = 0U;
ctrl_hum_reg.osrs_h = humidity_sampling;
- result = Write8(BME280_REGISTER_CONTROLHUMID, reinterpret_cast<uint8_t const&>(ctrl_hum_reg));
+ result |= Write8(BME280_REGISTER_CONTROLHUMID, reinterpret_cast<uint8_t const&>(ctrl_hum_reg));
ctrl_meas_reg.mode = mode;
ctrl_meas_reg.osrs_t = temperature_sampling;
@@ -160,7 +163,7 @@ Result BoschBME280::TakeMeasurement()
// Humidity
adc_humidity = 0;
result |= ReverseArray((uint8_t*)&adc_humidity, &array[3U+3U], 2U);
- // Ñalculating t_fine for calculation Pressure & Humidity
+ // Calculate t_fine for calculation Pressure & Humidity
(void) GetTemperature_x100();
}
}
@@ -320,6 +323,17 @@ Result BoschBME280::IsReadingCalibration(void)
}
// ******************************************************************************
+// *** Write register value(8-bit) ******************************************
+// ******************************************************************************
+Result BoschBME280::Write8(uint8_t reg, uint8_t value)
+{
+ uint8_t buf[2];
+ buf[0] = reg;
+ buf[1] = value;
+ return iic.Write(i2c_addr, buf, sizeof(buf));
+}
+
+// ******************************************************************************
// *** Read register value(8-bit unsigned) **********************************
// ******************************************************************************
Result BoschBME280::Read8(uint8_t reg, uint8_t& value)
@@ -336,17 +350,6 @@ Result BoschBME280::Read8(uint8_t reg, int8_t& value)
}
// ******************************************************************************
-// *** Write register value(8-bit) ******************************************
-// ******************************************************************************
-Result BoschBME280::Write8(uint8_t reg, uint8_t value)
-{
- uint8_t buf[2];
- buf[0] = reg;
- buf[1] = value;
- return iic.Write(i2c_addr, buf, sizeof(buf));
-}
-
-// ******************************************************************************
// *** Read register value(16-bit unsigned) *********************************
// ******************************************************************************
Result BoschBME280::Read16(uint8_t reg, uint16_t& value, bool reverse)
diff --git a/STM32F415APP/DevCore/Libraries/BoschBME280.h b/STM32F415APP/DevCore/Libraries/BoschBME280.h
index fe38c35..a46abfb 100644
--- a/STM32F415APP/DevCore/Libraries/BoschBME280.h
+++ b/STM32F415APP/DevCore/Libraries/BoschBME280.h
@@ -1,8 +1,8 @@
//******************************************************************************
-// @file DevCfg.h
+// @file BoschBME280.h
// @author Nicolai Shlapunov
//
-// @details Bosch BMPE280: Library, header
+// @details Bosch BME280: Library, header
//
// @section LICENSE
//
@@ -118,7 +118,7 @@ class BoschBME280
// *************************************************************************
// *** Initialize ******************************************************
// *************************************************************************
- Result Initialize();
+ Result Initialize(uint8_t addr = BME280_ADDRESS);
// *************************************************************************
// *** SetSampling *****************************************************
@@ -150,10 +150,25 @@ class BoschBME280
// *************************************************************************
int32_t GetHumidity_x1024(void);
+ // *************************************************************************
+ // *** GetTemperature **************************************************
+ // *************************************************************************
+ inline float GetTemperature(void) {return ((float)GetTemperature_x100() / 100.0F);}
+
+ // *************************************************************************
+ // *** GetPressure *****************************************************
+ // *************************************************************************
+ inline float GetPressure(void) {return ((float)GetPressure_x256() / 256.0F);}
+
+ // *************************************************************************
+ // *** GetHumidity *****************************************************
+ // *************************************************************************
+ inline float GetHumidity(void) {return ((float)GetHumidity_x1024() / 1024.0F);}
+
private:
// *** default I2C address **********************************************
- const uint8_t BME280_ADDRESS = 0x76;
+ static const uint8_t BME280_ADDRESS = 0x76;
// *** Register addresses *********************************************
enum Registers
@@ -301,6 +316,13 @@ class BoschBME280
// *** Reverse byte order in array *************************************
// *************************************************************************
Result ReverseArray(uint8_t* dst, uint8_t* src, uint32_t size);
+
+ // *************************************************************************
+ // *** Private: Constructors and assign operator - prevent copying *****
+ // *************************************************************************
+ BoschBME280();
+ BoschBME280(const BoschBME280&);
+ BoschBME280& operator=(const BoschBME280);
};
#endif
diff --git a/STM32F415APP/DevCore/Libraries/Eeprom24.cpp b/STM32F415APP/DevCore/Libraries/Eeprom24.cpp
index 0ed374f..82cfdde 100644
--- a/STM32F415APP/DevCore/Libraries/Eeprom24.cpp
+++ b/STM32F415APP/DevCore/Libraries/Eeprom24.cpp
@@ -20,6 +20,8 @@
// *****************************************************************************
#include "Eeprom24.h"
+#include "string.h" // for memcpy()
+
// *****************************************************************************
// *** Public: Init ********************************************************
// *****************************************************************************
diff --git a/STM32F415APP/DevCore/Libraries/Mlx90614.cpp b/STM32F415APP/DevCore/Libraries/Mlx90614.cpp
new file mode 100644
index 0000000..8de5731
--- /dev/null
+++ b/STM32F415APP/DevCore/Libraries/Mlx90614.cpp
@@ -0,0 +1,112 @@
+//******************************************************************************
+// @file Mlx90614.cpp
+// @author Nicolai Shlapunov
+//
+// @details DevCore: Bosch BME280 library, implementation
+//
+// @copyright Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "Mlx90614.h"
+
+// *****************************************************************************
+// *** Initialize **********************************************************
+// *****************************************************************************
+Result Mlx90614::Initialize(uint8_t addr)
+{
+ Result result = Result::RESULT_OK;
+
+ // Save I2C sensor address
+ i2c_addr = addr;
+
+ result = iic.Enable();
+
+ // TODO: read data from sensor
+
+ if(result.IsGood())
+ {
+ RtosTick::DelayMs(100U);
+ }
+
+ return result;
+}
+
+// ******************************************************************************
+// *** GetAmbientTemperature_x100 *******************************************
+// ******************************************************************************
+Result Mlx90614::GetAmbientTemperature_x100(int32_t& temp_x100)
+{
+ Result result = Result::RESULT_OK;
+
+ // Clear temperature for clear upper bits
+ temp_x100 = 0;
+ // Read object temperature
+ result = ReadReg(RAM_TA, *((uint16_t*)&temp_x100));
+ // Normalize temperature
+ temp_x100 *= 2; // Resolution is 0.02 degree C
+ temp_x100 -= 27315; // Result in Kelvins, so convert it to Celsius
+
+ return result;
+}
+
+// ******************************************************************************
+// *** GetObjectTemperature_x100 ********************************************
+// ******************************************************************************
+Result Mlx90614::GetObjectTemperature_x100(int32_t& temp_x100, ObjectType obj)
+{
+ Result result = Result::RESULT_OK;
+
+ // Clear temperature for clear upper bits
+ temp_x100 = 0;
+ // Read object temperature
+ result = ReadReg((obj == OBJECT1) ? RAM_TOBJ1 : RAM_TOBJ2, *((uint16_t*)&temp_x100));
+ // Normalize temperature
+ temp_x100 *= 2; // Resolution is 0.02 degree C
+ temp_x100 -= 27315; // Result in Kelvins, so convert it to Celsius
+
+ return result;
+}
+
+// ******************************************************************************
+// *** Read register value(16-bit unsigned) *********************************
+// ******************************************************************************
+Result Mlx90614::ReadReg(uint8_t reg, uint16_t& value)
+{
+ Result result = Result::RESULT_OK;
+
+ // Read data
+ result = iic.Transfer(i2c_addr, &reg, sizeof(reg), (uint8_t*)&value, sizeof(value));
+
+ // If the read succeeded, check error flag
+ if (value & 0x8000)
+ {
+ value = 0U;
+ result = Result::ERR_BUSY;
+ }
+
+ return result;
+}
+
+// ******************************************************************************
+// *** Write register value(16-bit signed) **********************************
+// ******************************************************************************
+Result Mlx90614::WriteReg(uint8_t reg, uint16_t value)
+{
+ Result result = Result::RESULT_OK;
+// uint8_t buf[2];
+// buf[0] = reg;
+// buf[1] = value;
+// return iic.Write(i2c_addr, buf, sizeof(buf));
+ return result;
+}
diff --git a/STM32F415APP/DevCore/Libraries/Mlx90614.h b/STM32F415APP/DevCore/Libraries/Mlx90614.h
new file mode 100644
index 0000000..1d4afae
--- /dev/null
+++ b/STM32F415APP/DevCore/Libraries/Mlx90614.h
@@ -0,0 +1,149 @@
+//******************************************************************************
+// @file Mlx90614.h
+// @author Nicolai Shlapunov
+//
+// @details Bosch BME280: Library, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2018, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef Mlx90614_h
+#define Mlx90614_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+#include "IIic.h"
+
+// *****************************************************************************
+// *** Bosch BME280 library *************************************************
+// *****************************************************************************
+class Mlx90614
+{
+ public:
+ // *************************************************************************
+ // *** Object enum *****************************************************
+ // *************************************************************************
+ enum ObjectType : uint8_t
+ {
+ OBJECT1 = 0U,
+ OBJECT2,
+ OBJECTS_CNT
+ };
+
+ // *************************************************************************
+ // *** Constructor *****************************************************
+ // *************************************************************************
+ Mlx90614(IIic& iic_ref) : iic(iic_ref) {};
+
+ // *************************************************************************
+ // *** Initialize ******************************************************
+ // *************************************************************************
+ Result Initialize(uint8_t addr = MLX90614_ADDRESS);
+
+ // *************************************************************************
+ // *** TakeMeasurement *************************************************
+ // *************************************************************************
+ Result TakeMeasurement();
+
+ // *************************************************************************
+ // *** GetObjectTemperature_x100 ***************************************
+ // *************************************************************************
+ Result GetAmbientTemperature_x100(int32_t& temp_x100);
+
+ // *************************************************************************
+ // *** GetObjectTemperature_x100 ***************************************
+ // *************************************************************************
+ Result GetObjectTemperature_x100(int32_t& temp_x100, ObjectType obj = OBJECT1);
+
+ private:
+
+ // *** default I2C address **********************************************
+ static const uint8_t MLX90614_ADDRESS = 0x5A;
+
+ // *** RAM Register addresses *****************************************
+ enum RamRegisters
+ {
+ RAM_RAWIR1 = 0x04,
+ RAM_RAWIR2 = 0x05,
+ RAM_TA = 0x06,
+ RAM_TOBJ1 = 0x07,
+ RAM_TOBJ2 = 0x08,
+ };
+
+ // *** EEPROM Register addresses **************************************
+ enum EepromRegisters
+ {
+ EEPROM_TOMAX = 0x20,
+ EEPROM_TOMIN = 0x21,
+ EEPROM_PWMCTRL = 0x22,
+ EEPROM_TARANGE = 0x23,
+ EEPROM_KE = 0x24,
+ EEPROM_CONFIG = 0x25,
+ EEPROM_ADDRESS = 0x2E,
+ EEPROM_ID0 = 0x3C,
+ EEPROM_ID1 = 0x3D,
+ EEPROM_ID2 = 0x3E,
+ EEPROM_ID3 = 0x3F,
+ EEPROM_SLEEP = 0xFF
+ };
+
+ // Reference to I2C interface
+ IIic& iic;
+ // I2C address
+ uint8_t i2c_addr = MLX90614_ADDRESS;
+
+ // Variables for store values
+ int32_t temperature = 0;
+
+ // *************************************************************************
+ // *** Read register value(16-bit unsigned) ****************************
+ // *************************************************************************
+ Result ReadReg(uint8_t reg, uint16_t& value);
+
+ // *************************************************************************
+ // *** Write register value(16-bit unsigned) ***************************
+ // *************************************************************************
+ Result WriteReg(uint8_t reg, uint16_t value);
+};
+
+#endif
diff --git a/STM32F415APP/DevCore/Libraries/Tcs34725.cpp b/STM32F415APP/DevCore/Libraries/Tcs34725.cpp
new file mode 100644
index 0000000..77a0ad2
--- /dev/null
+++ b/STM32F415APP/DevCore/Libraries/Tcs34725.cpp
@@ -0,0 +1,439 @@
+//******************************************************************************
+// @file Tcs34725.cpp
+// @author Nicolai Shlapunov
+//
+// @details DevCore: TCS34725 Sensor driver, implementation
+//
+// @copyright Copyright (c) 2019, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "Tcs34725.h"
+
+#include "string.h" // for memcpy()
+
+// *****************************************************************************
+// *** Public: Initialize **************************************************
+// *****************************************************************************
+Result Tcs34725::Initialize()
+{
+ Result result = Result::RESULT_OK;
+ iic.SetTxTimeout(10U);
+ iic.SetRxTimeout(10U);
+
+ result = iic.Enable();
+
+ if(result.IsGood())
+ {
+ uint8_t data = 0x00;
+ // Read Chip ID
+ result = Read8(REGISTER_ID, data);
+ if((data != 0x44) && (data != 0x4D)) // 0x44 = TCS34725, 0x4D = TCS34727
+ {
+ result = Result::ERR_I2C_GENERAL;
+ }
+ }
+
+ if(result.IsGood())
+ {
+ // Set internal inited flag
+ inited = true;
+ // Set default integration time and gain
+ SetIntegrationTime(integration_time);
+ SetGain(gain);
+ // At power up, the device initializes in a low-power Sleep state
+ Enable();
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Enable ******************************************************
+// *****************************************************************************
+Result Tcs34725::Enable(void)
+{
+ Result result = Result::RESULT_OK;
+
+ // Read current register state
+ uint8_t reg = 0;
+ result = Read8(REGISTER_ENABLE, reg);
+ // Turn on sensor
+ if(result.IsGood())
+ {
+ result = Write8(REGISTER_ENABLE, reg | ENABLE_PON);
+ }
+ // Writing a 1 activates the RGBC
+ if(result.IsGood())
+ {
+ RtosTick::DelayMs(3U); // There is a 2.4 ms warm-up delay if PON is enabled.
+ result |= Write8(REGISTER_ENABLE, ENABLE_PON | ENABLE_AEN);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Disable *****************************************************
+// *****************************************************************************
+Result Tcs34725::Disable(void)
+{
+ Result result = Result::RESULT_OK;
+
+ result = Write8(REGISTER_ENABLE, 0U);
+
+ // Read current register state
+ uint8_t reg = 0;
+ result = Read8(REGISTER_ENABLE, reg);
+ // Turn off sensor
+ if(result.IsGood())
+ {
+ result = Write8(REGISTER_ENABLE, reg & ~(ENABLE_PON | ENABLE_AEN));
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: SetGain *****************************************************
+// *****************************************************************************
+Result Tcs34725::SetGain(GainType g)
+{
+ Result result = Result::ERR_BUSY;
+
+ if(inited == true)
+ {
+ // Range check
+ if(g >= GAIN_CNT) g = GAIN_60X;
+ // Update register
+ result = Write8(REGISTER_CONTROL, g);
+ // Update value
+ gain = g;
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: IncGain *****************************************************
+// *****************************************************************************
+Result Tcs34725::IncGain(void)
+{
+ Result result = Result::ERR_BUSY;
+
+ if(gain < GAIN_60X)
+ {
+ result = SetGain((GainType)(gain + 1U));
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: DecGain *****************************************************
+// *****************************************************************************
+Result Tcs34725::DecGain(void)
+{
+ Result result = Result::ERR_BUSY;
+
+ if(gain > GAIN_1X)
+ {
+ result = SetGain((GainType)(gain - 1U));
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: GetGainValue ************************************************
+// *****************************************************************************
+uint32_t Tcs34725::GetGainValue(GainType g)
+{
+ uint32_t gain_value = 0U;
+ // Check for default value
+ if(g == GAIN_CNT)
+ {
+ g = gain;
+ }
+ // Convert gain to a integer value
+ switch(g)
+ {
+ case GAIN_60X:
+ gain_value = 60U;
+ break;
+
+ case GAIN_16X:
+ gain_value = 16U;
+ break;
+
+ case GAIN_4X:
+ gain_value = 4U;
+ break;
+
+ case GAIN_1X: // Intentional fall-trough
+ default:
+ gain_value = 1U;
+ break;
+ }
+ // Return result
+ return gain_value;
+}
+
+// *****************************************************************************
+// *** Public: SetIntegrationTime ******************************************
+// *****************************************************************************
+Result Tcs34725::SetIntegrationTime(IntegrationTimeType it)
+{
+ Result result = Result::ERR_BUSY;
+
+ if(inited == true)
+ {
+ // Update register
+ result = Write8(REGISTER_ATIME, it);
+ // Update value
+ integration_time = it;
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: IsDataReady *************************************************
+// *****************************************************************************
+Result Tcs34725::IsDataReady(bool& is_ready)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(inited == true)
+ {
+ uint8_t data = 0x00;
+ // Read Chip ID
+ result = Read8(REGISTER_STATUS, data);
+ if(data & STATUS_AVALID)
+ {
+ is_ready = true;
+ }
+ else
+ {
+ is_ready = false;
+ }
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: GetRawData **************************************************
+// *****************************************************************************
+Result Tcs34725::GetRawData(uint16_t& r, uint16_t& g, uint16_t& b, uint16_t& c)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ if(inited == true)
+ {
+ result = Read16(REGISTER_CDATAL, c);
+ result |= Read16(REGISTER_RDATAL, r);
+ result |= Read16(REGISTER_GDATAL, g);
+ result |= Read16(REGISTER_BDATAL, b);
+ // If good - store to calculate color temperature in future
+ if(result.IsGood())
+ {
+ red = r;
+ green = g;
+ blue = b;
+ clear = c;
+ }
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: GetLux ******************************************************
+// *****************************************************************************
+Result Tcs34725::GetLux(uint16_t& lux)
+{
+ Result result = Result::ERR_BUSY;
+
+ if(inited == true)
+ {
+ // AMS RGB sensors have no direct IR channel and the IR content must be
+ // calculated indirectly
+ uint16_t ir = (red + green + blue > clear) ? (red + green + blue - clear) / 2 : 0;
+
+ // Remove the IR component from the raw RGB values
+ uint16_t r = red - ir;
+ uint16_t g = green - ir;
+ uint16_t b = blue - ir;
+
+ // Calculate the counts per lux (CPL)
+ float cpl = (((256 - integration_time) * 2.4f) * GetGainValue()) / (1.0f * 310.0f);
+
+ // Finally, calculate the lux
+ lux = (0.136f * (float)r + 1.000f * (float)g - 0.444f * (float)b) / cpl;
+
+ result = Result::RESULT_OK;
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: GetColorTemperature *****************************************
+// *****************************************************************************
+Result Tcs34725::GetColorTemperature(uint16_t& color_temperature)
+{
+ Result result = Result::ERR_BUSY;
+
+ if(inited == true)
+ {
+ // AMS RGB sensors have no direct IR channel and the IR content must be
+ // calculated indirectly
+ uint16_t ir = (red + green + blue > clear) ? (red + green + blue - clear) / 2 : 0;
+
+ // Remove the IR component from the raw RGB values
+ uint16_t r = red - ir;
+ uint16_t b = blue - ir;
+
+ // A simple method of measuring color temp is to use the ratio of blue
+ // to red light, taking IR cancellation into account.
+ color_temperature = (3810U * (uint32_t)b) / (uint32_t)r + 1391U;
+
+ result = Result::RESULT_OK;
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: SetLimits ***************************************************
+// *****************************************************************************
+Result Tcs34725::SetLimits(uint16_t low, uint16_t high)
+{
+ Result result = Result::RESULT_OK;
+
+ if(inited == true)
+ {
+ result = Write8(REGISTER_AILTL, low & 0xFF);
+ result |= Write8(REGISTER_AILTH, low >> 8);
+ result |= Write8(REGISTER_AIHTL, high & 0xFF);
+ result |= Write8(REGISTER_AIHTH, high >> 8);
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: SetInterrupt ************************************************
+// *****************************************************************************
+Result Tcs34725::SetInterrupt(bool enable)
+{
+ Result result = Result::RESULT_OK;
+
+ if(inited == true)
+ {
+ // Read current register state
+ uint8_t reg = 0U;
+ result = Read8(REGISTER_ENABLE, reg);
+ // Turn on sensor
+ if(result.IsGood())
+ {
+ // Set or clear flag
+ reg = (enable == true) ? (reg | ENABLE_AIEN) : (reg & ~ENABLE_AIEN);
+ // Write new register value
+ result = Write8(REGISTER_ENABLE, reg | ENABLE_PON);
+ }
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: ClearInterrupt **********************************************
+// *****************************************************************************
+Result Tcs34725::ClearInterrupt(void)
+{
+ Result result = Result::RESULT_OK;
+
+ if(inited == true)
+ {
+ // Magic value for clear channel interrupt clear
+ uint8_t command = COMMAND_BIT | 0x66;
+ // Write command
+ result = iic.Write(i2c_addr, &command, sizeof(command));
+ }
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Read ********************************************************
+// *****************************************************************************
+Result Tcs34725::Read(uint16_t addr, uint8_t* rx_buf_ptr, uint16_t size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ return result;
+}
+
+// *****************************************************************************
+// *** Public: Write *******************************************************
+// *****************************************************************************
+Result Tcs34725::Write(uint16_t addr, uint8_t* tx_buf_ptr, uint16_t size)
+{
+ Result result = Result::ERR_NULL_PTR;
+
+ return result;
+}
+
+// ******************************************************************************
+// *** Write register value(8-bit) ******************************************
+// ******************************************************************************
+Result Tcs34725::Write8(uint8_t reg, uint8_t value)
+{
+ uint8_t buf[2];
+ buf[0] = reg | COMMAND_BIT;
+ buf[1] = value;
+ return iic.Write(i2c_addr, buf, sizeof(buf));
+}
+
+// ******************************************************************************
+// *** Read register value(8-bit unsigned) **********************************
+// ******************************************************************************
+Result Tcs34725::Read8(uint8_t reg, uint8_t& value)
+{
+ // Add command bit
+ reg |= COMMAND_BIT;
+ // Transfer & return result
+ return iic.Transfer(i2c_addr, &reg, sizeof(reg), (uint8_t*)&value, sizeof(value));
+}
+
+// ******************************************************************************
+// *** Read register value(16-bit unsigned) *********************************
+// ******************************************************************************
+Result Tcs34725::Read16(uint8_t reg, uint16_t& value, bool reverse)
+{
+ Result result = Result::RESULT_OK;
+
+ // Add command bit
+ reg |= COMMAND_BIT;
+ // Read data
+ result = iic.Transfer(i2c_addr, &reg, sizeof(reg), (uint8_t*)&value, sizeof(value));
+ // Change endian if needed
+ if(reverse)
+ {
+ value = (value >> 8) | (value << 8);
+ }
+
+ return result;
+}
diff --git a/STM32F415APP/DevCore/Libraries/Tcs34725.h b/STM32F415APP/DevCore/Libraries/Tcs34725.h
new file mode 100644
index 0000000..d09916b
--- /dev/null
+++ b/STM32F415APP/DevCore/Libraries/Tcs34725.h
@@ -0,0 +1,298 @@
+//******************************************************************************
+// @file Tcs34725.h
+// @author Nicolai Shlapunov
+//
+// @details DevCore: TCS34725 Sensor driver, header
+//
+// @section LICENSE
+//
+// Software License Agreement (Modified BSD License)
+//
+// Copyright (c) 2019, Devtronic & Nicolai Shlapunov
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the Devtronic nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+// 4. Redistribution and use of this software other than as permitted under
+// this license is void and will automatically terminate your rights under
+// this license.
+//
+// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// @section SUPPORT
+//
+// Devtronic invests time and resources providing this open source code,
+// please support Devtronic and open-source hardware/software by
+// donations and/or purchasing products from Devtronic.
+//
+//******************************************************************************
+
+#ifndef Tcs34725_h
+#define Tcs34725_h
+
+// *****************************************************************************
+// *** Includes ************************************************************
+// *****************************************************************************
+#include "DevCfg.h"
+#include "IIic.h"
+
+// *****************************************************************************
+// *** EEPROM 24C*** Driver Class ******************************************
+// *****************************************************************************
+class Tcs34725
+{
+ public:
+ // *************************************************************************
+ // *** Public: Gain enum ***********************************************
+ // *************************************************************************
+ enum GainType : uint8_t
+ {
+ GAIN_1X = 0x00, // 1x
+ GAIN_4X = 0x01, // 4x
+ GAIN_16X = 0x02, // 16x
+ GAIN_60X = 0x03, // 60x
+ GAIN_CNT
+ };
+
+ // *************************************************************************
+ // *** Public: Integration Time enum ***********************************
+ // *************************************************************************
+ enum IntegrationTimeType : uint8_t
+ {
+ INTEGRATIONTIME_2_4MS = 0xFF, // 1 cycle, 2.4ms, Max Count: 1024
+ INTEGRATIONTIME_24MS = 0xF6, // 10 cycles, 24ms, Max Count: 10240
+ INTEGRATIONTIME_50MS = 0xEB, // 20 cycles, 50ms, Max Count: 20480
+ INTEGRATIONTIME_101MS = 0xD5, // 42 cycles, 101ms, Max Count: 43008
+ INTEGRATIONTIME_154MS = 0xC0, // 64 cycles, 154ms, Max Count: 65535
+ INTEGRATIONTIME_700MS = 0x00 // 256 cycles, 700ms, Max Count: 65535
+ };
+
+ // *************************************************************************
+ // *** Public: Wait Time enum ******************************************
+ // *************************************************************************
+ enum WaitTimeVType : uint8_t
+ {
+ WTIME_2_4MS = 0xFF, // WLONG0 = 2.4ms, WLONG1 = 0.029s
+ WTIME_204MS = 0xAB, // WLONG0 = 204ms, WLONG1 = 2.45s
+ WTIME_614MS = 0x00 // WLONG0 = 614ms, WLONG1 = 7.4s
+ };
+
+ // *************************************************************************
+ // *** Public: Constructor *********************************************
+ // *************************************************************************
+ explicit Tcs34725(IIic& iic_ref) : iic(iic_ref) {};
+
+ // *************************************************************************
+ // *** Public: Initialize **********************************************
+ // *************************************************************************
+ Result Initialize();
+
+ // *************************************************************************
+ // *** Public: Enable **************************************************
+ // *************************************************************************
+ Result Enable(void);
+
+ // *************************************************************************
+ // *** Public: Enable **************************************************
+ // *************************************************************************
+ Result Disable(void);
+
+ // *************************************************************************
+ // *** Public: SetGain *************************************************
+ // *************************************************************************
+ Result SetGain(GainType g);
+
+ // *************************************************************************
+ // *** Public: IncGain *************************************************
+ // *************************************************************************
+ Result IncGain(void);
+
+ // *************************************************************************
+ // *** Public: DecGain *************************************************
+ // *************************************************************************
+ Result DecGain(void);
+
+ // *************************************************************************
+ // *** Public: GetGainValue ********************************************
+ // *************************************************************************
+ uint32_t GetGainValue(GainType g = GAIN_CNT);
+
+ // *************************************************************************
+ // *** Public: SetIntegrationTime **************************************
+ // *************************************************************************
+ Result SetIntegrationTime(IntegrationTimeType it);
+
+ // *************************************************************************
+ // *** Public: IsDataReady *********************************************
+ // *************************************************************************
+ Result IsDataReady(bool& is_ready);
+
+ // *************************************************************************
+ // *** Public: GetRawData **********************************************
+ // *************************************************************************
+ Result GetRawData(uint16_t& r, uint16_t& g, uint16_t& b, uint16_t& c);
+
+ // *************************************************************************
+ // *** Public: GetLux **************************************************
+ // *************************************************************************
+ Result GetLux(uint16_t& lux);
+
+ // *************************************************************************
+ // *** Public: GetColorTemperature *************************************
+ // *************************************************************************
+ Result GetColorTemperature(uint16_t& color_temperature);
+
+ // *************************************************************************
+ // *** Public: SetLimits ***********************************************
+ // *************************************************************************
+ Result SetLimits(uint16_t low, uint16_t high);
+
+ // *************************************************************************
+ // *** Public: SetInterrupt ********************************************
+ // *************************************************************************
+ Result SetInterrupt(bool enable);
+
+ // *************************************************************************
+ // *** Public: ClearInterrupt ******************************************
+ // *************************************************************************
+ Result ClearInterrupt(void);
+
+ // *************************************************************************
+ // *** Public: Read ****************************************************
+ // *************************************************************************
+ Result Read(uint16_t addr, uint8_t* rx_buf_ptr, uint16_t size);
+
+ // *************************************************************************
+ // *** Public: Write ***************************************************
+ // *************************************************************************
+ Result Write(uint16_t addr, uint8_t* tx_buf_ptr, uint16_t size);
+
+ private:
+
+ enum RegisterType : uint8_t
+ {
+ REGISTER_ENABLE = 0x00,
+ REGISTER_ATIME = 0x01, // Integration time
+ REGISTER_WTIME = 0x03, // Wait time(when ENABLE_WEN is set)
+ REGISTER_AILTL = 0x04, // Clear channel lower interrupt threshold (Lo)
+ REGISTER_AILTH = 0x05, // Clear channel lower interrupt threshold (Hi)
+ REGISTER_AIHTL = 0x06, // Clear channel upper interrupt threshold (Lo)
+ REGISTER_AIHTH = 0x07, // Clear channel upper interrupt threshold (Hi)
+ REGISTER_PERS = 0x0C, // Persistence register - basic SW filtering mechanism for interrupts
+ REGISTER_CONFIG = 0x0D,
+ REGISTER_CONTROL = 0x0F, // Set the gain level for the sensor
+ REGISTER_ID = 0x12, // 0x44 = TCS34721/TCS34725, 0x4D = TCS34723/TCS34727
+ REGISTER_STATUS = 0x13,
+ REGISTER_CDATAL = 0x14, // Clear channel data (Lo)
+ REGISTER_CDATAH = 0x15, // Clear channel data (Hi)
+ REGISTER_RDATAL = 0x16, // Red channel data (Lo)
+ REGISTER_RDATAH = 0x17, // Red channel data (Hi)
+ REGISTER_GDATAL = 0x18, // Green channel data (Lo)
+ REGISTER_GDATAH = 0x19, // Green channel data (Hi)
+ REGISTER_BDATAL = 0x1A, // Blue channel data (Lo)
+ REGISTER_BDATAH = 0x1B // Blue channel data (Hi)
+ };
+
+ enum EnableRegisterValueType : uint8_t
+ {
+ ENABLE_AIEN = 0x10, // RGBC Interrupt Enable
+ ENABLE_WEN = 0x08, // Wait Enable - Writing 1 activate the wait timer
+ ENABLE_AEN = 0x02, // RGBC Enable - Writing 1 activate the ADC, 0 disables it
+ ENABLE_PON = 0x01 // Power on - Writing 1 activates the internal oscillator, 0 disables it
+ };
+
+ enum StatusRegisterValueType : uint8_t
+ {
+ STATUS_AINT = 0x10, // RGBC Clean channel interrupt
+ STATUS_AVALID = 0x01 // Indicates that the RGBC channels have completed an integration cycle
+ };
+
+ enum ConfigRegisterValueType : uint8_t
+ {
+ CONFIG_WLONG = 0x02 // Choose between short and long (12x) wait times via REGISTER_WTIME
+ };
+
+ enum PersRegisterValueType : uint8_t
+ {
+ PERS_NONE = 0b0000, // Every RGBC cycle generates an interrupt
+ PERS_1_CYCLE = 0b0001, // 1 clear channel value outside of threshold range
+ PERS_2_CYCLE = 0b0010, // 2 clear channel consecutive values out of range
+ PERS_3_CYCLE = 0b0011, // 3 clean channel consecutive values out of range
+ PERS_5_CYCLE = 0b0100, // 5 clean channel consecutive values out of range
+ PERS_10_CYCLE = 0b0101, // 10 clean channel consecutive values out of range
+ PERS_15_CYCLE = 0b0110, // 15 clean channel consecutive values out of range
+ PERS_20_CYCLE = 0b0111, // 20 clean channel consecutive values out of range
+ PERS_25_CYCLE = 0b1000, // 25 clean channel consecutive values out of range
+ PERS_30_CYCLE = 0b1001, // 30 clean channel consecutive values out of range
+ PERS_35_CYCLE = 0b1010, // 35 clean channel consecutive values out of range
+ PERS_40_CYCLE = 0b1011, // 40 clean channel consecutive values out of range
+ PERS_45_CYCLE = 0b1100, // 45 clean channel consecutive values out of range
+ PERS_50_CYCLE = 0b1101, // 50 clean channel consecutive values out of range
+ PERS_55_CYCLE = 0b1110, // 55 clean channel consecutive values out of range
+ PERS_60_CYCLE = 0b1111 // 60 clean channel consecutive values out of range
+ };
+
+ // Command bit
+ static const uint8_t COMMAND_BIT = 0x80U;
+
+ // Default chip address
+ static const uint8_t I2C_ADDR = 0x29U;
+
+ // Reference to the I2C handle
+ IIic& iic;
+ // I2C address
+ uint8_t i2c_addr = I2C_ADDR;
+
+ // Parameters
+ bool inited = false;
+ GainType gain = GAIN_1X;
+ IntegrationTimeType integration_time = INTEGRATIONTIME_154MS;
+
+ // Last values
+ uint16_t red = 0U;
+ uint16_t green = 0U;
+ uint16_t blue = 0U;
+ uint16_t clear = 0U;
+
+ // *************************************************************************
+ // *** Write register value(8-bit) *************************************
+ // *************************************************************************
+ Result Write8(uint8_t reg, uint8_t value);
+
+ // *************************************************************************
+ // *** Read register value(8-bit unsigned) *****************************
+ // *************************************************************************
+ Result Read8(uint8_t reg, uint8_t& value);
+
+ // *************************************************************************
+ // *** Read register value(16-bit unsigned) ****************************
+ // *************************************************************************
+ Result Read16(uint8_t reg, uint16_t& value, bool reverse = false);
+
+ // *************************************************************************
+ // *** Private: Constructors and assign operator - prevent copying *****
+ // *************************************************************************
+ Tcs34725();
+ Tcs34725(const Tcs34725&);
+ Tcs34725& operator=(const Tcs34725);
+};
+
+#endif
diff --git a/STM32F415APP/DevCore/Tasks/InputDrv.cpp b/STM32F415APP/DevCore/Tasks/InputDrv.cpp
index 5375a3e..0bfd743 100644
--- a/STM32F415APP/DevCore/Tasks/InputDrv.cpp
+++ b/STM32F415APP/DevCore/Tasks/InputDrv.cpp
@@ -381,6 +381,13 @@ bool InputDrv::GetButtonState(PortType port, ButtonType button, bool& btn_state)
return ret;
}
+// *****************************************************************************
+// *** Get encoder counts from last call - CAN BE CALLED FROM ONE TASK *****
+// *****************************************************************************
+int32_t InputDrv::GetEncoderState(PortType port)
+{
+ return GetEncoderState(port, last_enc_value[port]);
+}
// *****************************************************************************
// *** Get encoder counts from last call ***********************************
@@ -400,7 +407,7 @@ int32_t InputDrv::GetEncoderState(PortType port, int32_t& last_enc_val)
// *****************************************************************************
// *** Get encoder button state ********************************************
// *****************************************************************************
-bool InputDrv::GetEncoderButtonState(PortType port, EncButtonType button)
+bool InputDrv::GetEncoderButtonCurrentState(PortType port, EncButtonType button)
{
// Return current state of button
return encoders[port].btn[button].btn_state;
@@ -409,6 +416,14 @@ bool InputDrv::GetEncoderButtonState(PortType port, EncButtonType button)
// *****************************************************************************
// *** Get encoder button state ********************************************
// *****************************************************************************
+bool InputDrv::GetEncoderButtonState(PortType port, EncButtonType button)
+{
+ return GetEncoderButtonState(port, button, enc_btn_value[port][button]);
+}
+
+// *****************************************************************************
+// *** Get encoder button state ********************************************
+// *****************************************************************************
bool InputDrv::GetEncoderButtonState(PortType port, EncButtonType button, bool& btn_state)
{
bool ret = false;
@@ -528,30 +543,38 @@ InputDrv::ExtDeviceType InputDrv::DetectDeviceType(PortType port)
// Variable to store Y axis value
int32_t y_val;
- // Config ADC for measure
- if(port == EXT_LEFT) ConfigADC(EXT_DEV_JOY, EXT_DEV_NONE);
- if(port == EXT_RIGHT) ConfigADC(EXT_DEV_NONE, EXT_DEV_JOY);
- // Start measurement
- HAL_ADCEx_InjectedStart(hadc);
- // Wait until End of Conversion flag is raised
- while(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_JEOC));
- x_val = HAL_ADCEx_InjectedGetValue(hadc, (port << 1) + 1);
- y_val = HAL_ADCEx_InjectedGetValue(hadc, (port << 1) + 2);
-
- // Center values
- x_val -= ADC_MAX_VAL/2;
- y_val -= ADC_MAX_VAL/2;
- // If at least one value near center
- if( ((x_val > -JOY_THRESHOLD) && (x_val < JOY_THRESHOLD))
- || ((y_val > -JOY_THRESHOLD) && (y_val < JOY_THRESHOLD)))
- {
- // Joystick connected
- ret = EXT_DEV_JOY;
+ if(hadc != nullptr)
+ {
+ // Config ADC for measure
+ if(port == EXT_LEFT) ConfigADC(EXT_DEV_JOY, EXT_DEV_NONE);
+ if(port == EXT_RIGHT) ConfigADC(EXT_DEV_NONE, EXT_DEV_JOY);
+ // Start measurement
+ HAL_ADCEx_InjectedStart(hadc);
+ // Wait until End of Conversion flag is raised
+ while(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_JEOC));
+ x_val = HAL_ADCEx_InjectedGetValue(hadc, (port << 1) + 1);
+ y_val = HAL_ADCEx_InjectedGetValue(hadc, (port << 1) + 2);
+
+ // Center values
+ x_val -= ADC_MAX_VAL/2;
+ y_val -= ADC_MAX_VAL/2;
+ // If at least one value near center
+ if( ((x_val > -JOY_THRESHOLD) && (x_val < JOY_THRESHOLD))
+ || ((y_val > -JOY_THRESHOLD) && (y_val < JOY_THRESHOLD)))
+ {
+ // Joystick connected
+ ret = EXT_DEV_JOY;
+ }
+ else
+ {
+ // Stop ADC before switch to digital inputs
+ HAL_ADCEx_InjectedStop(hadc);
+ // Config input IO to digital
+ ConfigInputIO(true, port);
+ }
}
else
{
- // Stop ADC before switch to digital inputs
- HAL_ADCEx_InjectedStop(hadc);
// Config input IO to digital
ConfigInputIO(true, port);
}
diff --git a/STM32F415APP/DevCore/Tasks/InputDrv.h b/STM32F415APP/DevCore/Tasks/InputDrv.h
index e9d6a50..f268afb 100644
--- a/STM32F415APP/DevCore/Tasks/InputDrv.h
+++ b/STM32F415APP/DevCore/Tasks/InputDrv.h
@@ -160,6 +160,11 @@ class InputDrv : public AppTask
bool GetButtonState(PortType port, ButtonType button, bool& btn_state);
// *************************************************************************
+ // *** Get encoder counts from last call - CAN BE CALLED FROM ONE TASK *
+ // *************************************************************************
+ int32_t GetEncoderState(PortType port);
+
+ // *************************************************************************
// *** Get encoder counts from last call *******************************
// *************************************************************************
// * Return state of encoder. Class counts encoder clicks and stored inside.
@@ -172,12 +177,18 @@ class InputDrv : public AppTask
// *** Get button state ************************************************
// *************************************************************************
// Return button state: true - pressed, false - unpressed
+ bool GetEncoderButtonCurrentState(PortType port, EncButtonType button);
+
+ // *************************************************************************
+ // *** Get encoder button state - CAN BE CALLED FROM ONE TASK **********
+ // *************************************************************************
+ // Return button state: true - state changed, false - state remain
bool GetEncoderButtonState(PortType port, EncButtonType button);
// *************************************************************************
// *** Get encoder button state ****************************************
// *************************************************************************
- // Return button state: true - pressed, false - unpressed
+ // Return button state: true - state changed, false - state remain
bool GetEncoderButtonState(PortType port, EncButtonType button, bool& btn_state);
// *************************************************************************
@@ -347,6 +358,14 @@ class InputDrv : public AppTask
ADC_HandleTypeDef* hadc = nullptr;
// *************************************************************************
+ // *** Last value for reduce overhead in user task *********************
+ // *************************************************************************
+ // Encoder values
+ int32_t last_enc_value[EXT_MAX] = {0};
+ // Encoder button states
+ bool enc_btn_value[EXT_MAX][ENC_BTN_MAX] = {0};
+
+ // *************************************************************************
// *** Process Button Input function ***********************************
// *************************************************************************
void ProcessButtonInput(ButtonProfile& button);
diff --git a/STM32F415APP/DevCore/UiEngine/UiButton.h b/STM32F415APP/DevCore/UiEngine/UiButton.h
index 5f768f8..dc74682 100644
--- a/STM32F415APP/DevCore/UiEngine/UiButton.h
+++ b/STM32F415APP/DevCore/UiEngine/UiButton.h
@@ -85,6 +85,11 @@ class UiButton : public VisObject
void* clbk_ptr, void* clbk_param_ptr, uint32_t clbk_param);
// *************************************************************************
+ // *** SetActive *******************************************************
+ // *************************************************************************
+ void SetActive(bool is_active) {active = is_active;}
+
+ // *************************************************************************
// *** Put line in buffer **********************************************
// *************************************************************************
virtual void DrawInBufH(uint16_t* buf, int32_t n, int32_t row, int32_t y = 0);
@@ -100,10 +105,13 @@ class UiButton : public VisObject
virtual void Action(VisObject::ActionType action, int32_t tx, int32_t ty);
private:
- // Callback params
+ // Callback function pointer
void (*callback)(void* ptr, void* param_ptr, uint32_t param) = nullptr;
+ // Pointer to something(usually object)
void* ptr = nullptr;
+ // Callback parameter pointer
void* param_ptr = nullptr;
+ // Callback parameter
uint32_t param = 0U;
// String pointer
const char* str = nullptr;