LwOW 3.0.0 documentation¶
Welcome to the documentation for version 3.0.0.
LwOW is lightweight, platform independent library for Onewire protocol for embedded systems. Its primary focus is UART hardware for physical communication for sensors and other slaves.
Download library · Getting started · Open Github
Features¶
Written in ANSI C99
Platform independent, uses custom low-level layer for device drivers
1-Wire protocol fits UART specifications at
9600
and115200
baudsHardware is responsible for timing characteristics
Allows DMA on the high-performance microcontrollers
Different device drivers included
DS18x20 temperature sensor is natively supported
Works with operating system due to hardware timing management
Separate thread-safe API is available
API for device scan, reading and writing single bits
User friendly MIT license
Requirements¶
C compiler
Platform dependent drivers
Few kB of non-volatile memory
Contribute¶
Fresh contributions are always welcome. Simple instructions to proceed:
Fork Github repository
Respect C style & coding rules used by the library
Create a pull request to
develop
branch with new features or bug fixes
Alternatively you may:
Report a bug
Ask for a feature request
License¶
MIT License
Copyright (c) 2020 Tilen MAJERLE
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Table of contents¶
Getting started¶
Download library¶
Library is primarly hosted on Github.
Download latest release from releases area on Github
Clone develop branch for latest development
Download from releases¶
All releases are available on Github releases area.
Clone from Github¶
First-time clone¶
Download and install
git
if not alreadyOpen console and navigate to path in the system to clone repository to. Use command
cd your_path
Clone repository with one of available
3
optionsRun
git clone --recurse-submodules https://github.com/MaJerle/lwow
command to clone entire repository, including submodulesRun
git clone --recurse-submodules --branch develop https://github.com/MaJerle/lwow
to clone development branch, including submodulesRun
git clone --recurse-submodules --branch master https://github.com/MaJerle/lwow
to clone latest stable branch, including submodules
Navigate to
examples
directory and run favourite example
Update cloned to latest version¶
Open console and navigate to path in the system where your resources repository is. Use command
cd your_path
Run
git pull origin master --recurse-submodules
command to pull latest changes and to fetch latest changes from submodulesRun
git submodule foreach git pull origin master
to update & merge all submodules
Note
This is preferred option to use when you want to evaluate library and run prepared examples. Repository consists of multiple submodules which can be automatically downloaded when cloning and pulling changes from root repository.
Add library to project¶
At this point it is assumed that you have successfully download library, either cloned it or from releases page.
Copy
lwow
folder to your projectAdd
lwow/src/include
folder to include path of your toolchainAdd source files from
lwow/src/
folder to toolchain buildCopy
lwow/src/include/lwow/lwow_opts_template.h
to project folder and rename it tolwow_opts.h
Implement device drivers for UART hardware
Build the project
Configuration file¶
Library comes with template config file, which can be modified according to needs.
This file shall be named lwow_opts.h
and its default template looks like the one below:
Tip
Check LwOW configuration section for possible configuration settings
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /**
* \file lwow_opts_template.h
* \brief LwOW application configuration
*/
/*
* Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* This file is part of LwOW - Lightweight onewire library.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v3.0.0
*/
#ifndef LWOW_HDR_OPTS_H
#define LWOW_HDR_OPTS_H
/* Rename this file to "lwow_opts.h" for your application */
/*
* Open "include/lwow/lwow_opt.h" and
* copy & replace here settings you want to change values
*/
#endif /* LWOW_HDR_OPTS_H */
|
User manual¶
How it works¶
LwOW library tends to use UART hardware of any microcontroller/embedded system, to generate timing clock for OneWire signals.
Nowaways embedded systems allow many UART ports, usually many more vs requirements for the final application. OneWire protocol needs precise timings and embedded systems (in 99.9%) do not have specific hardware to handle communication of this type.
Fortunately, OneWire timings match with UART timings at 9600
and 115200
bauds.
Note
Check detailed tutorial from Maxim for more information.
Thread safety¶
With default configuration, library is not thread safe. This means whenever it is used with operating system, user must resolve it with care.
Library has locking mechanism support for thread safety, which needs to be enabled.
Tip
To enable thread-safety support, parameter LWOW_CFG_OS
must be set to 1
.
Please check LwOW configuration for more information about other options.
After thread-safety features has been enabled, it is necessary to implement
4
low-level system functions.
Tip
System function template example is available in lwow/src/system/
folder.
Example code for CMSIS-OS V2
Note
Check System functions section for function description
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /**
* \file lwow_sys_cmsis_os.c
* \brief System functions for CMSIS-OS based operating system
*/
/*
* Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* This file is part of LwOW - Lightweight onewire library.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v3.0.0
*/
#include "lwow/lwow.h"
#if LWOW_CFG_OS && !__DOXYGEN__
#include "cmsis_os.h"
uint8_t
lwow_sys_mutex_create(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
const osMutexAttr_t attr = {
.attr_bits = osMutexRecursive
};
*mutex = osMutexNew(&attr); /* Create new mutex */
LWOW_UNUSED(arg);
return 1;
}
uint8_t
lwow_sys_mutex_delete(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
LWOW_UNUSED(arg);
osMutexDelete(*mutex); /* Delete mutex */
return 1;
}
uint8_t
lwow_sys_mutex_wait(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
if (osMutexAcquire(*mutex, osWaitForever) != osOK) {
return 0;
}
LWOW_UNUSED(arg);
return 1;
}
uint8_t
lwow_sys_mutex_release(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
if (osMutexRelease(*mutex) != osOK) {
return 0;
}
LWOW_UNUSED(arg);
return 1;
}
#endif /* LWOW_CFG_OS && !__DOXYGEN__ */
|
Hardware connection with sensor¶
To be able to successfully use sensors and other devices with embedded systems, these needs to be physically wired with embedded system (or PC).
Target devices (usually sensors or memory devices) are connected to master host device using single wire (from here protocol name One Wire) for communication only. There are also voltage and ground lines, marked as VCC and GND, respectively.
At this point, we assume you are familiar with UART protocol and you understand it has 2
independent lines, one for transmitting data (TX) and second to receive data (RX).
For successful communication with sensors, bi-directional support is necessary to be implemented, but there is only 1
wire available to do so. It might sound complicated at this point.
OneWire data line is by default in open-drain mode. This means that:
Any device connected to data line can at any time pull line to GND without fear of short circuit
None of the devices are allowed to force high state on the line. Application must use external pull-up resistor to do so.
How to send data over TX pin if application cannot force high level on the line? There are 2
options:
Configure UART TX pin to open-drain mode
Use push-pull to open-drain converter using 2 mosfets and 1 resistor
Since many latest embedded systems allow you to configure TX pin to open-drain mode natively, you may consider second option instead.
Warning
Application must assure that TX pin is always configured to open-drain mode, either with push-pull to open-drain converter or directly configured in the system.
TX and RX pins¶
Every communication starts by master initiating it. To transfer data over UART, application uses TX pin and RX pin is used to read data. With 1-Wire protocol, application needs to transfer data and read them back in real-time. This is also called loop-back mode.
Let’s take reset sequence as an example. By specifications, UART has to be configured in 9600
bauds and master needs to send single UART byte with value of 0xF0
. If there is any slave connected, slave must pull line to GND during transmision 0f 0xF
part of byte. Master needs to identify this by using RX pin of the UART.
Note
Please check official document on Maxim website to understand why 0xF0
and 9600
bauds.
UART and 1-Wire timing relation¶
This part is explaining how UART and 1-Wire timings are connected together and what is important to take into consideration for stable and reliable communication.
1-Wire protocol specification match UART protocol specification when baudrate is configured at 115200
bauds.
Going into the details about 1-Wire protocol, we can identify that:
To send
1
logical bit at 1-Wire level, application needs to transmit1
byte at UART level with speed of115200
baudsTo send
1
logical byte at 1-Wire level, application must transmit8
bytes at UART level with speed of115200
bauds
Timing for each bit is very clearly defined by 1-Wire specification (not purpose to go into these details) and needs to respect all low and high level states for reliable communication. Each bit at 1-Wire level starts with master pulling line low for specific amount of time. Until master initiates communication, line is in idle mode.
Image above shows relation between UART and 1-Wire timing. It represents transmission of 3
bits on 1-Wire level or 3
bytes at UART level. Green and blue rectangles show different times between ending of one bit and start of new bit.
Note
By 1-Wire specification, it is important to match bit timing. It is less important to match idle timings as these are not defined. Effectively this allows master to use UART to initiate byte transfer where UART takes care of proper timing.
Different timings (green vs blue) may happen if application uses many interrupts, but uses UART in polling mode to transmit data. This is very important for operating systems where context switch may disable interrupts. Fortunately, it is not a problem for reliable communication due to:
When UART starts transmission, hardware takes care of timing
If application gets preempted with more important task, 1-Wire line will be in idle state for longer time. This is not an issue by 1-Wire specification
More advanced embedded systems implement DMA controllers to support next level of transfers.
Porting guide¶
Implement low-level driver¶
Implementation of low-level driver is an essential part. It links middleware with actual hardware design of the device.
Its implementation must provide 4
functions:
To open/configure UART hardware
To set UART baudrate on the fly
To transmit/receive data over UART
To close/de-init UART hardware
After these functions have been implemented (check below for references),
driver must link these functions to single driver structure of type lwow_ll_drv_t
,
later used during instance initialization.
Tip
Check Low-level driver for function prototypes.
Implement system functions¶
System functions are required only if operating system mode is enabled, with LWOW_CFG_OS
.
Its implementation structure is not the same as for low-level driver,
customer needs to implement fixed functions, with pre-defined name, starting with ow_sys_
name.
System function must only support OS mutex management and has to provide:
ow_sys_mutex_create()
function to create new mutexow_sys_mutex_delete()
function to delete existing mutexow_sys_mutex_wait()
function to wait for mutex to be availableow_sys_mutex_release()
function to release (give) mutex back
Warning
Application must define LWOW_CFG_OS_MUTEX_HANDLE
for mutex type.
This shall be done in lwow_opts.h
file.
Tip
Check System functions for function prototypes.
Example: Low-level driver for WIN32¶
Example code for low-level porting on WIN32 platform. It uses native Windows features to open COM port and read/write from/to it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | /**
* \file lwow_ll_win32.c
* \brief UART implementation for WIN32
*/
/*
* Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* This file is part of LwOW - Lightweight onewire library.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v3.0.0
*/
#include <stdio.h>
#include "lwow/lwow.h"
#include "windows.h"
#if !__DOXYGEN__
/* Function prototypes */
static uint8_t init(void* arg);
static uint8_t deinit(void* arg);
static uint8_t set_baudrate(uint32_t baud, void* arg);
static uint8_t transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg);
/* Win 32 LL driver for OW */
const lwow_ll_drv_t
lwow_ll_drv_win32 = {
.init = init,
.deinit = deinit,
.set_baudrate = set_baudrate,
.tx_rx = transmit_receive,
};
static HANDLE com_port;
static DCB dcb = { 0 };
static uint8_t
init(void* arg) {
dcb.DCBlength = sizeof(dcb);
/* Open virtual file as read/write */
com_port = CreateFile(L"\\\\.\\COM4",
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
NULL
);
/* First read current values */
if (GetCommState(com_port, &dcb)) {
COMMTIMEOUTS timeouts;
dcb.BaudRate = 115200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
/* Try to set com port data */
if (!SetCommState(com_port, &dcb)) {
printf("Cannot get COM port\r\n");
return 0;
}
if (GetCommTimeouts(com_port, &timeouts)) {
/* Set timeout to return immediatelly from ReadFile function */
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
if (!SetCommTimeouts(com_port, &timeouts)) {
printf("Cannot set COM PORT timeouts\r\n");
}
GetCommTimeouts(com_port, &timeouts);
}
} else {
printf("Cannot get COM port info\r\n");
}
return 1;
}
uint8_t
deinit(void* arg) {
/* Disable UART peripheral */
return 1;
}
uint8_t
set_baudrate(uint32_t baud, void* arg) {
/* Configure UART to selected baudrate */
dcb.BaudRate = baud;
/* Try to set com port data */
if (!SetCommState(com_port, &dcb)) {
printf("Cannot set COM port baudrate to %u bauds\r\n", (unsigned)baud);
return 0;
}
return 1;
}
uint8_t
transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg) {
/* Perform data exchange */
size_t read = 0;
DWORD br;
if (com_port != NULL) {
/*
* Flush any data in RX buffer.
* This helps to reset communication in case of on-the-fly device management
* if one-or-more device(s) are added or removed.
*
* Any noise on UART level could start byte and put it to Win buffer,
* preventing to read aligned data from it
*/
PurgeComm(com_port, PURGE_RXCLEAR | PURGE_RXABORT);
/* Write file and send data */
WriteFile(com_port, tx, len, &br, NULL);
FlushFileBuffers(com_port);
/* Read same amount of data as sent previously (loopback) */
do {
if (ReadFile(com_port, rx, (DWORD)(len - read), &br, NULL)) {
read += (size_t)br;
rx += (size_t)br;
}
} while (read < len);
}
return 1;
}
#endif /* !__DOXYGEN__ */
|
Example: Low-level driver for STM32¶
Example code for low-level porting on STM32 platform.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | /**
* \file lwow_ll_stm32.c
* \brief Generic UART implementation for STM32 MCUs
*/
/*
* Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* This file is part of LwOW - Lightweight onewire library.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v3.0.0
*/
/*
* How it works
*
* https://docs.majerle.eu/projects/lwow/en/latest/user-manual/hw_connection.html#
*/
#include "lwow/lwow.h"
#if !__DOXYGEN__
static uint8_t init(void* arg);
static uint8_t deinit(void* arg);
static uint8_t set_baudrate(uint32_t baud, void* arg);
static uint8_t transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg);
/* STM32 LL driver for OW */
const lwow_ll_drv_t
lwow_ll_drv_stm32 = {
.init = init,
.deinit = deinit,
.set_baudrate = set_baudrate,
.tx_rx = transmit_receive,
};
static LL_USART_InitTypeDef
usart_init;
static uint8_t
init(void* arg) {
LL_GPIO_InitTypeDef gpio_init;
/* Peripheral clock enable */
ONEWIRE_USART_CLK_EN;
ONEWIRE_TX_PORT_CLK_EN;
ONEWIRE_RX_PORT_CLK_EN;
/* Configure GPIO pins */
LL_GPIO_StructInit(&gpio_init);
gpio_init.Mode = LL_GPIO_MODE_ALTERNATE;
gpio_init.Speed = LL_GPIO_SPEED_FREQ_HIGH;
gpio_init.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
gpio_init.Pull = LL_GPIO_PULL_UP;
/* TX pin */
gpio_init.Alternate = ONEWIRE_TX_PIN_AF;
gpio_init.Pin = ONEWIRE_TX_PIN;
LL_GPIO_Init(ONEWIRE_TX_PORT, &gpio_init);
/* RX pin */
gpio_init.Alternate = ONEWIRE_RX_PIN_AF;
gpio_init.Pin = ONEWIRE_RX_PIN;
LL_GPIO_Init(ONEWIRE_RX_PORT, &gpio_init);
/* Configure UART peripherals */
LL_USART_DeInit(ONEWIRE_USART);
LL_USART_StructInit(&usart_init);
usart_init.BaudRate = 9600;
usart_init.DataWidth = LL_USART_DATAWIDTH_8B;
usart_init.StopBits = LL_USART_STOPBITS_1;
usart_init.Parity = LL_USART_PARITY_NONE;
usart_init.TransferDirection = LL_USART_DIRECTION_TX_RX;
usart_init.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
usart_init.OverSampling = LL_USART_OVERSAMPLING_16;
LL_USART_Init(ONEWIRE_USART, &usart_init);
LL_USART_ConfigAsyncMode(ONEWIRE_USART);
LWOW_UNUSED(arg);
return 1;
}
static uint8_t
deinit(void* arg) {
LL_USART_DeInit(ONEWIRE_USART);
LWOW_UNUSED(arg);
return 1;
}
static uint8_t
set_baudrate(uint32_t baud, void* arg) {
usart_init.BaudRate = baud;
LL_USART_Init(ONEWIRE_USART, &usart_init);
LL_USART_ConfigAsyncMode(ONEWIRE_USART);
LWOW_UNUSED(arg);
return 1;
}
static uint8_t
transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg) {
const uint8_t* t = tx;
uint8_t* r = rx;
/* Send byte with polling */
LL_USART_Enable(ONEWIRE_USART);
for (; len > 0; --len, ++t, ++r) {
LL_USART_TransmitData8(ONEWIRE_USART, *t);
while (!LL_USART_IsActiveFlag_TXE(ONEWIRE_USART));
while (!LL_USART_IsActiveFlag_RXNE(ONEWIRE_USART));
*r = LL_USART_ReceiveData8(ONEWIRE_USART);
}
while (!LL_USART_IsActiveFlag_TC(ONEWIRE_USART)) {}
LL_USART_Disable(ONEWIRE_USART);
LWOW_UNUSED(arg);
return 1;
}
#endif /* !__DOXYGEN__ */
|
Example: System functions for WIN32¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /**
* \file lwow_sys_win32.c
* \brief System functions for WIN32
*/
/*
* Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* This file is part of LwOW - Lightweight onewire library.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v3.0.0
*/
#include "lwow/lwow.h"
#include "windows.h"
#if LWOW_CFG_OS && !__DOXYGEN__
uint8_t
lwow_sys_mutex_create(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
*mutex = CreateMutex(NULL, 0, NULL);
return 1;
}
uint8_t
lwow_sys_mutex_delete(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
CloseHandle(*mutex);
*mutex = NULL;
return 1;
}
uint8_t
lwow_sys_mutex_wait(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0;
}
uint8_t
lwow_sys_mutex_release(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
return ReleaseMutex(*mutex);
}
#endif /* LWOW_CFG_OS && !__DOXYGEN__ */
|
Example: System functions for CMSIS-OS¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /**
* \file lwow_sys_cmsis_os.c
* \brief System functions for CMSIS-OS based operating system
*/
/*
* Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* This file is part of LwOW - Lightweight onewire library.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v3.0.0
*/
#include "lwow/lwow.h"
#if LWOW_CFG_OS && !__DOXYGEN__
#include "cmsis_os.h"
uint8_t
lwow_sys_mutex_create(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
const osMutexAttr_t attr = {
.attr_bits = osMutexRecursive
};
*mutex = osMutexNew(&attr); /* Create new mutex */
LWOW_UNUSED(arg);
return 1;
}
uint8_t
lwow_sys_mutex_delete(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
LWOW_UNUSED(arg);
osMutexDelete(*mutex); /* Delete mutex */
return 1;
}
uint8_t
lwow_sys_mutex_wait(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
if (osMutexAcquire(*mutex, osWaitForever) != osOK) {
return 0;
}
LWOW_UNUSED(arg);
return 1;
}
uint8_t
lwow_sys_mutex_release(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
if (osMutexRelease(*mutex) != osOK) {
return 0;
}
LWOW_UNUSED(arg);
return 1;
}
#endif /* LWOW_CFG_OS && !__DOXYGEN__ */
|
Low-Level driver for STM32 with STM32CubeMX¶
Specific low-level driver has been implemented for STM32 series of microcontrollers, to allow easy and simple link of LwOW library with projects generated with STM32CubeMX or STm32CubeIDE development tools.
Driver is based on HAL (Hardware Abstraction Layer) and it uses interrupt configuration to transmit/receive data. When customer starts a new project using CubeMX, it must:
Configure specific UART IP as async mode both directions
UART must have enabled global interrupts, to allow transmitting/receiving data using interrupts
Application must pass pointer to UART handle when calling
ow_init
function
Tip
Special example has been developed to demonstrate how can application use
multiple OneWire instances on multiple UART ports at the same time.
It uses custom argument to determine which UART handle shall be used for data transmit.
Check /examples/stm32/
folder for actual implementation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | /**
* \file lwow_ll_stm32_hal.c
* \brief UART driver implementation for STM32 with HAL code
*/
/*
* Copyright (c) 2020 Tilen MAJERLE
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* This file is part of LwOW - Lightweight onewire library.
*
* Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v3.0.0
*/
/*
* How it works (general)
*
* https://docs.majerle.eu/projects/lwow/en/latest/user-manual/hw_connection.html#
*
* This specific driver is optimized for proejcts generated by STM32CubeMX or STM32CubeIDE with HAL drivers
* It can be used w/ or w/o operating system and it uses interrupts & polling for data receive and data transmit.
*
* Application must pass pointer to UART handle as argument to ow_init function in order
* to link OW instance with actual UART hardware used for OW instance.
*
* To use this driver, application must:
* - Enable interrupt in CubeMX to allow HAL_UART_Receive_IT functionality
* - Use pointer to UART handle when initializing ow with ow_init
*/
#include "lwow/lwow.h"
#include "main.h" /* Generated normally by CubeMX */
#if !__DOXYGEN__
static uint8_t init(void* arg);
static uint8_t deinit(void* arg);
static uint8_t set_baudrate(uint32_t baud, void* arg);
static uint8_t transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg);
/* STM32 LL driver for OW */
const lwow_ll_drv_t
lwow_ll_drv_stm32_hal = {
.init = init,
.deinit = deinit,
.set_baudrate = set_baudrate,
.tx_rx = transmit_receive,
};
static uint8_t
init(void* arg) {
UART_HandleTypeDef* huart = arg;
LWOW_ASSERT0("arg != NULL", arg != NULL);
/* Initialize UART */
HAL_UART_DeInit(huart);
return HAL_UART_Init(huart) == HAL_OK;
}
static uint8_t
deinit(void* arg) {
UART_HandleTypeDef* huart = arg;
LWOW_ASSERT0("arg != NULL", arg != NULL);
return HAL_UART_DeInit(huart);
}
static uint8_t
set_baudrate(uint32_t baud, void* arg) {
UART_HandleTypeDef* huart = arg;
LWOW_ASSERT0("arg != NULL", arg != NULL);
huart->Init.BaudRate = baud;
return init(huart);
}
static uint8_t
transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg) {
UART_HandleTypeDef* huart = arg;
uint32_t start;
LWOW_ASSERT0("arg != NULL", arg != NULL);
/* Get current HAL tick */
start = HAL_GetTick();
/* Start RX in interrupt mode */
HAL_UART_Receive_IT(huart, rx, len);
/* Process TX in polling mode */
HAL_UART_Transmit(huart, (void*)tx, len, 100);
/* Wait RX to finish */
while (huart->RxState != HAL_UART_STATE_READY) {
if (HAL_GetTick() - start > 100) {
return 0;
}
}
return 1;
}
#endif /* !__DOXYGEN__ */
|
API reference¶
List of all the modules:
LwOW¶
-
group
LWOW
Lightweight onewire.
- Note
Functions with
_raw
suffix do no implement locking mechanism when used with operating system.
Defines
-
LWOW_UNUSED
(x)¶ Unused variable macro
-
LWOW_ASSERT
(msg, c)¶ Assert check function.
It returns lwowERRPAR if condition check fails
- Parameters
[in] msg
: Optional message parameter to print on failure[in] c
: Condition to check for
-
LWOW_ASSERT0
(msg, c)¶ Assert check function with return
0
It returns
0
if condition check fails- Parameters
[in] msg
: Optional message parameter to print on failure[in] c
: Condition to check for
-
LWOW_ARRAYSIZE
(x)¶ Get size of statically declared array.
- Return
Number of array elements
- Parameters
[in] x
: Input array
-
LWOW_CMD_RSCRATCHPAD
¶ Read scratchpad command for 1-Wire devices
-
LWOW_CMD_WSCRATCHPAD
¶ Write scratchpad command for 1-Wire devices
-
LWOW_CMD_CPYSCRATCHPAD
¶ Copy scratchpad command for 1-Wire devices
-
LWOW_CMD_RECEEPROM
¶ Read EEPROM command
-
LWOW_CMD_RPWRSUPPLY
¶ Read power supply command
-
LWOW_CMD_SEARCHROM
¶ Search ROM command
-
LWOW_CMD_READROM
¶ Read ROM command
-
LWOW_CMD_MATCHROM
¶ Match ROM command. Select device with specific ROM
-
LWOW_CMD_SKIPROM
¶ Skip ROM, select all devices
Typedefs
-
typedef lwowr_t (*
lwow_search_cb_fn
)(lwow_t *const ow, const lwow_rom_t *const rom_id, size_t index, void *arg)¶ Search callback function implementation.
- Return
- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: Rom address when new device detected. Set toNULL
when search finished[in] index
: Current device index Whenrom_id = NULL
, value indicates number of total devices found[in] arg
: Custom user argument
Enums
-
enum
lwowr_t
¶ 1-Wire result enumeration
Values:
-
enumerator
lwowOK
= 0x00¶ Device returned OK
-
enumerator
lwowERRPRESENCE
¶ Presence was not successful
-
enumerator
lwowERRNODEV
¶ No device connected, maybe device removed during scan?
-
enumerator
lwowERRTXRX
¶ Error while exchanging data
-
enumerator
lwowERRBAUD
¶ Error setting baudrate
-
enumerator
lwowERRPAR
¶ Parameter error
-
enumerator
lwowERR
¶ General-Purpose error
-
enumerator
Functions
-
lwowr_t
lwow_init
(lwow_t *const ow, const lwow_ll_drv_t *const ll_drv, void *arg)¶ Initialize OneWire instance.
-
void
lwow_deinit
(lwow_t *const ow)¶ Deinitialize OneWire instance.
- Parameters
[in] ow
: OneWire instance
-
lwowr_t
lwow_protect
(lwow_t *const ow, const uint8_t protect)¶ Protect 1-wire from concurrent access.
-
lwowr_t
lwow_unprotect
(lwow_t *const ow, const uint8_t protect)¶ Unprotect 1-wire from concurrent access.
-
lwowr_t
lwow_write_byte_ex_raw
(lwow_t *const ow, const uint8_t btw, uint8_t *const br)¶ Write byte over OW and read its response.
-
lwowr_t
lwow_write_byte_ex
(lwow_t *const ow, const uint8_t btw, uint8_t *const br)¶ Write byte over OW and read its response.
-
lwowr_t
lwow_search_raw
(lwow_t *const ow, lwow_rom_t *const rom_id)¶ Search for devices on 1-wire bus.
- Note
To reset search and to start over, use lwow_search_reset function
- Return
- Parameters
[inout] ow
: 1-Wire handle[out] rom_id
: Pointer to ROM structure to save ROM
-
lwowr_t
lwow_search
(lwow_t *const ow, lwow_rom_t *const rom_id)¶ Search for devices on 1-wire bus.
- Note
To reset search and to start over, use lwow_search_reset function
- Return
- Note
This function is thread-safe
- Parameters
[inout] ow
: 1-Wire handle[out] rom_id
: Pointer to ROM structure to save ROM
-
lwowr_t
lwow_search_with_command_raw
(lwow_t *const ow, const uint8_t cmd, lwow_rom_t *const rom_id)¶ Search for devices on 1-wire bus with custom search command.
- Note
To reset search and to start over, use lwow_search_reset function
- Return
- Parameters
[inout] ow
: 1-Wire handle[in] cmd
: command to use for search operation[out] rom_id
: Pointer to ROM structure to store address
-
lwowr_t
lwow_search_with_command
(lwow_t *const ow, const uint8_t cmd, lwow_rom_t *const rom_id)¶ Search for devices on 1-wire bus with custom search command.
- Note
To reset search and to start over, use lwow_search_reset function
- Return
- Note
This function is thread-safe
- Parameters
[inout] ow
: 1-Wire handle[in] cmd
: command to use for search operation[out] rom_id
: Pointer to ROM structure to store address
-
lwowr_t
lwow_search_with_command_callback
(lwow_t *const ow, const uint8_t cmd, size_t *const roms_found, const lwow_search_cb_fn func, void *const arg)¶ Search devices on 1-wire network by using callback function and custom search command.
When new device is detected, callback function
func
is called to notify user- Return
- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[in] cmd
: 1-Wire search command[out] roms_found
: Output variable to save number of found devices. Set toNULL
if not used[in] func
: Callback function to call for each device[in] arg
: Custom user argument, used in callback function
-
lwowr_t
lwow_search_with_callback
(lwow_t *const ow, size_t *const roms_found, const lwow_search_cb_fn func, void *const arg)¶ Search devices on 1-wire network by using callback function and
SEARCH_ROM
1-Wire command.When new device is detected, callback function
func
is called to notify user- Return
- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[out] roms_found
: Output variable to save number of found devices. Set toNULL
if not used[in] func
: Callback function to call for each device[in] arg
: Custom user argument, used in callback function
-
lwowr_t
lwow_search_devices_with_command_raw
(lwow_t *const ow, const uint8_t cmd, lwow_rom_t *const rom_id_arr, const size_t rom_len, size_t *const roms_found)¶ Search for devices on 1-Wire network with command and store ROM IDs to input array.
- Return
- Parameters
[in] ow
: 1-Wire handle[in] cmd
: 1-Wire search command[in] rom_id_arr
: Pointer to output array to store found ROM IDs into[in] rom_len
: Length of input ROM array[out] roms_found
: Output variable to save number of found devices. Set toNULL
if not used
-
lwowr_t
lwow_search_devices_with_command
(lwow_t *const ow, const uint8_t cmd, lwow_rom_t *const rom_id_arr, const size_t rom_len, size_t *const roms_found)¶ Search for devices on 1-Wire network with command and store ROM IDs to input array.
- Return
- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[in] cmd
: 1-Wire search command[in] rom_id_arr
: Pointer to output array to store found ROM IDs into[in] rom_len
: Length of input ROM array[out] roms_found
: Output variable to save number of found devices. Set toNULL
if not used
-
lwowr_t
lwow_search_devices_raw
(lwow_t *const ow, lwow_rom_t *const rom_id_arr, const size_t rom_len, size_t *const roms_found)¶ Search for devices on 1-Wire network with default command and store ROM IDs to input array.
-
lwowr_t
lwow_search_devices
(lwow_t *const ow, lwow_rom_t *const rom_id_arr, const size_t rom_len, size_t *const roms_found)¶ Search for devices on 1-Wire network with default command and store ROM IDs to input array.
- Return
- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[in] rom_id_arr
: Pointer to output array to store found ROM IDs into[in] rom_len
: Length of input ROM array[out] roms_found
: Output variable to save number of found devices. Set toNULL
if not used
-
lwowr_t
lwow_match_rom_raw
(lwow_t *const ow, const lwow_rom_t *const rom_id)¶ Select device on 1-wire network with exact ROM number.
-
lwowr_t
lwow_match_rom
(lwow_t *const ow, const lwow_rom_t *const rom_id)¶ Select device on 1-wire network with exact ROM number.
-
lwowr_t
lwow_skip_rom_raw
(lwow_t *const ow)¶ Skip ROM address and select all devices on the network.
-
uint8_t
lwow_crc
(const void *const in, const size_t len)¶ Calculate CRC-8 of input data.
- Return
Calculated CRC
- Note
This function is reentrant
- Parameters
[in] in
: Input data[in] len
: Number of bytes
-
uint8_t
lwow_write_byte_raw
(lwow_t *const ow, const uint8_t b)¶ Write byte over 1-wire protocol.
- Note
This function is deprecated. Use lwow_write_byte_ex_raw instead
- Return
Received byte over 1-wire protocol
- Parameters
[inout] ow
: 1-Wire handle[in] b
: Byte to write
-
uint8_t
lwow_write_byte
(lwow_t *const ow, const uint8_t b)¶ Write byte over 1-wire protocol.
- Note
This function is deprecated. Use lwow_write_byte_ex_raw instead
- Return
Received byte over 1-wire protocol
- Note
This function is deprecated. Use lwow_write_byte_ex instead
- Note
This function is thread-safe
- Parameters
[inout] ow
: 1-Wire handle[in] b
: Byte to write
-
uint8_t
lwow_read_byte_raw
(lwow_t *const ow)¶ Read next byte on 1-Wire.
- Note
This function is deprecated. Use lwow_read_byte_ex_raw instead
- Return
Byte read over 1-Wire
- Parameters
[inout] ow
: 1-Wire handle
-
uint8_t
lwow_read_byte
(lwow_t *const ow)¶ Read next byte on 1-Wire.
- Note
This function is deprecated. Use lwow_read_byte_ex_raw instead
- Return
Byte read over 1-Wire
- Note
This function is deprecated. Use lwow_read_byte_ex instead
- Note
This function is thread-safe
- Parameters
[inout] ow
: 1-Wire handle
-
uint8_t
lwow_read_bit_raw
(lwow_t *const ow)¶ Read single bit on 1-Wire network.
- Note
This function is deprecated. Use lwow_read_bit_ex_raw instead
- Return
Bit value
- Parameters
[inout] ow
: 1-Wire handle
-
uint8_t
lwow_read_bit
(lwow_t *const ow)¶ Read single bit on 1-Wire network.
- Note
This function is deprecated. Use lwow_read_bit_ex_raw instead
- Return
Bit value
- Note
This function is deprecated. Use lwow_read_bit_ex instead
- Note
This function is thread-safe
- Parameters
[inout] ow
: 1-Wire handle
-
struct
lwow_rom_t
¶ - #include <lwow.h>
ROM structure.
Public Members
-
uint8_t
rom
[8]¶ 8-bytes ROM address
-
uint8_t
-
struct
lwow_t
¶ - #include <lwow.h>
1-Wire structure
Public Members
-
lwow_rom_t
rom
¶ ROM address of last device found. When searching for new devices, we always need last found address, to be able to decide which way to go next time during scan.
-
uint8_t
disrepancy
¶ Disrepancy value on last search
-
void *
arg
¶ User custom argument
-
const lwow_ll_drv_t *
ll_drv
¶ Low-level functions driver
-
LWOW_CFG_OS_MUTEX_HANDLE
mutex
¶ Mutex handle
-
lwow_rom_t
LwOW configuration¶
This is the default configuration of the middleware.
When any of the settings shall be modified, it shall be done in dedicated application config lwow_opts.h
file.
Note
Check Getting started to create configuration file.
-
group
LWOW_OPT
OW options.
Defines
-
LWOW_CFG_OS
¶ Enables
1
or disables0
operating system support in the library.- Note
When
LWOW_CFG_OS
is enabled, user must implement functions in System functions group.
-
LWOW_CFG_OS_MUTEX_HANDLE
¶ Mutex handle type.
- Note
This value must be set in case LWOW_CFG_OS is set to
1
. If data type is not known to compiler, include header file with definition before you define handle type
-
Platform specific¶
List of all the modules:
Low-level driver¶
-
group
LWOW_LL
Low-level device dependant functions.
-
struct
lwow_ll_drv_t
¶ - #include <lwow.h>
1-Wire low-level driver structure
Public Members
-
uint8_t (*
init
)(void *arg)¶ Initialize low-level driver.
- Return
1
on success,0
otherwise- Parameters
[in] arg
: Custom argument passed to lwow_init function
-
uint8_t (*
deinit
)(void *arg)¶ De-initialize low-level driver.
- Return
1
on success,0
otherwise- Parameters
[in] arg
: Custom argument passed to lwow_init function
-
uint8_t (*
set_baudrate
)(uint32_t baud, void *arg)¶ Set UART baudrate.
- Return
1
on success,0
otherwise- Parameters
[in] baud
: Baudrate to set in units of bauds, normally9600
or115200
[in] arg
: Custom argument passed to lwow_init function
-
uint8_t (*
tx_rx
)(const uint8_t *tx, uint8_t *rx, size_t len, void *arg)¶ Transmit and receive bytes over UART hardware (or custom implementation)
Bytes array for
tx
is already prepared to be directly transmitted over UART hardware, no data manipulation is necessary.At the same time, library must read received data on RX port and put it to
rx
data array, one by one, up tolen
number of bytes- Return
1
on success,0
otherwise- Parameters
[in] tx
: Data to transmit over UART[out] rx
: Array to write received data to[in] len
: Number of bytes to exchange[in] arg
: Custom argument passed to lwow_init function
-
uint8_t (*
-
struct
System functions¶
System function are used in conjunction with thread safety. These are required when operating system is used and multiple threads want to access to the same OneWire instance.
Tip
Check Thread safety and Porting guide for instructions on how to port.
Below is a list of function prototypes and its implementation details.
-
group
LWOW_SYS
System functions when used with operating system.
Functions
-
uint8_t
lwow_sys_mutex_create
(LWOW_CFG_OS_MUTEX_HANDLE *mutex, void *arg)¶ Create a new mutex and assign value to handle.
- Return
1
on success,0
otherwise- Parameters
[out] mutex
: Output variable to save mutex handle[in] arg
: User argument passed on lwow_init function
-
uint8_t
lwow_sys_mutex_delete
(LWOW_CFG_OS_MUTEX_HANDLE *mutex, void *arg)¶ Delete existing mutex and invalidate mutex variable.
- Return
1
on success,0
otherwise- Parameters
[in] mutex
: Mutex handle to remove and invalidate[in] arg
: User argument passed on lwow_init function
-
uint8_t
Device drivers¶
List of all supported device drivers
DS18x20 temperature sensor¶
-
group
LWOW_DEVICE_DS18x20
Device driver for DS18x20 temperature sensor.
- Note
Functions with
_raw
suffix do no implement locking mechanism when using with operating system.
Defines
-
LWOW_DS18X20_ALARM_DISABLE
¶ Disable alarm temperature
-
LWOW_DS18X20_ALARM_NOCHANGE
¶ Do not modify current alarm settings
-
LWOW_DS18X20_TEMP_MIN
¶ Minimum temperature
-
LWOW_DS18X20_TEMP_MAX
¶ Maximal temperature
Functions
-
uint8_t
lwow_ds18x20_start_raw
(lwow_t *const ow, const lwow_rom_t *const rom_id)¶ Start temperature conversion on specific (or all) devices.
- Return
1
on success,0
otherwise- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to start measurement for. Set toNULL
to start measurement on all devices at the same time
-
uint8_t
lwow_ds18x20_start
(lwow_t *const ow, const lwow_rom_t *const rom_id)¶ Start temperature conversion on specific (or all) devices.
- Return
1
on success,0
otherwise- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to start measurement for. Set toNULL
to start measurement on all devices at the same time
-
uint8_t
lwow_ds18x20_read_raw
(lwow_t *const ow, const lwow_rom_t *const rom_id, float *const t)¶ Read temperature previously started with lwow_ds18x20_start.
- Return
1
on success,0
otherwise- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to read data from[out] t
: Pointer to output float variable to save temperature
-
uint8_t
lwow_ds18x20_read
(lwow_t *const ow, const lwow_rom_t *const rom_id, float *const t)¶ Read temperature previously started with lwow_ds18x20_start.
- Return
1
on success,0
otherwise- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to read data from[out] t
: Pointer to output float variable to save temperature
-
uint8_t
lwow_ds18x20_set_resolution_raw
(lwow_t *const ow, const lwow_rom_t *const rom_id, const uint8_t bits)¶ Set resolution for
DS18B20
sensor.- Note
DS18S20
has fixed9-bit
resolution- Return
1
on success,0
otherwise- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to set resolution[in] bits
: Number of resolution bits. Possible values are9 - 12
-
uint8_t
lwow_ds18x20_set_resolution
(lwow_t *const ow, const lwow_rom_t *const rom_id, const uint8_t bits)¶ Set resolution for
DS18B20
sensor.- Note
DS18S20
has fixed9-bit
resolution- Return
1
on success,0
otherwise- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to set resolution[in] bits
: Number of resolution bits. Possible values are9 - 12
-
uint8_t
lwow_ds18x20_get_resolution_raw
(lwow_t *const ow, const lwow_rom_t *const rom_id)¶ Get resolution for
DS18B20
device.- Return
Resolution in units of bits (
9 - 12
) on success,0
otherwise- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to get resolution from
-
uint8_t
lwow_ds18x20_get_resolution
(lwow_t *const ow, const lwow_rom_t *const rom_id)¶ Get resolution for
DS18B20
device.- Return
Resolution in units of bits (
9 - 12
) on success,0
otherwise- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to get resolution from
-
uint8_t
lwow_ds18x20_set_alarm_temp_raw
(lwow_t *const ow, const lwow_rom_t *const rom_id, int8_t temp_l, int8_t temp_h)¶ Set/clear temperature alarm high/low levels in units of degree Celcius.
Example usage would look something similar to:
//Set alarm temperature; low = 10°C, high = 30°C lwow_ds18x20_set_alarm_temp(&ow, dev_id, 10, 30); //Set alarm temperature; low = disable, high = no change lwow_ds18x20_set_alarm_temp(&ow, dev_id, LWOW_DS18X20_ALARM_DISABLE, LWOW_DS18X20_ALARM_NOCHANGE); //Set alarm temperature; low = no change, high = disable lwow_ds18x20_set_alarm_temp(&ow, dev_id, LWOW_DS18X20_ALARM_NOCHANGE, LWOW_DS18X20_ALARM_DISABLE); //Set alarm temperature; low = 10°C, high = 30°C lwow_ds18x20_set_alarm_temp(&ow, dev_id, 10, 30);
- Note
temp_h
andtemp_l
are high and low temperature alarms and can accept different values:-55 % 125
, valid temperature rangeLWOW_DS18X20_ALARM_DISABLE to disable temperature alarm (either high or low)
LWOW_DS18X20_ALARM_NOCHANGE to keep current alarm temperature (either high or low)
- Return
1
on success,0
otherwise- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address[in] temp_l
: Alarm low temperature[in] temp_h
: Alarm high temperature
-
uint8_t
lwow_ds18x20_set_alarm_temp
(lwow_t *const ow, const lwow_rom_t *const rom_id, int8_t temp_l, int8_t temp_h)¶ Set/clear temperature alarm high/low levels in units of degree Celcius.
Example usage would look something similar to:
//Set alarm temperature; low = 10°C, high = 30°C lwow_ds18x20_set_alarm_temp(&ow, dev_id, 10, 30); //Set alarm temperature; low = disable, high = no change lwow_ds18x20_set_alarm_temp(&ow, dev_id, LWOW_DS18X20_ALARM_DISABLE, LWOW_DS18X20_ALARM_NOCHANGE); //Set alarm temperature; low = no change, high = disable lwow_ds18x20_set_alarm_temp(&ow, dev_id, LWOW_DS18X20_ALARM_NOCHANGE, LWOW_DS18X20_ALARM_DISABLE); //Set alarm temperature; low = 10°C, high = 30°C lwow_ds18x20_set_alarm_temp(&ow, dev_id, 10, 30);
- Note
temp_h
andtemp_l
are high and low temperature alarms and can accept different values:-55 % 125
, valid temperature rangeLWOW_DS18X20_ALARM_DISABLE to disable temperature alarm (either high or low)
LWOW_DS18X20_ALARM_NOCHANGE to keep current alarm temperature (either high or low)
- Return
1
on success,0
otherwise- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address[in] temp_l
: Alarm low temperature[in] temp_h
: Alarm high temperature
-
lwowr_t
lwow_ds18x20_search_alarm_raw
(lwow_t *const ow, lwow_rom_t *const rom_id)¶ Search for
DS18x20
devices with alarm flag.- Note
To reset search, use lwow_search_reset function
- Return
- Parameters
[in] ow
: 1-Wire handle[out] rom_id
: Pointer to 8-byte long variable to save ROM
-
lwowr_t
lwow_ds18x20_search_alarm
(lwow_t *const ow, lwow_rom_t *const rom_id)¶ Search for
DS18x20
devices with alarm flag.- Note
To reset search, use lwow_search_reset function
- Return
- Note
This function is thread-safe
- Parameters
[in] ow
: 1-Wire handle[out] rom_id
: Pointer to 8-byte long variable to save ROM
-
uint8_t
lwow_ds18x20_is_b
(lwow_t *const ow, const lwow_rom_t *const rom_id)¶ Check if ROM address matches
DS18B20
device.- Return
1
on success,0
otherwise- Note
This function is reentrant
- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to test againstDS18B20
-
uint8_t
lwow_ds18x20_is_s
(lwow_t *const ow, const lwow_rom_t *const rom_id)¶ Check if ROM address matches
DS18S20
device.- Return
1
on success,0
otherwise- Note
This function is reentrant
- Parameters
[in] ow
: 1-Wire handle[in] rom_id
: 1-Wire device address to test againstDS18S20
Examples and demos¶
Various examples are provided for fast library evaluation on embedded systems. These are optimized prepared and maintained for 2
platforms, but could be easily extended to more platforms:
WIN32 examples, prepared as Visual Studio Community projects
ARM Cortex-M examples for STM32, prepared as STM32CubeIDE GCC projects
Warning
Library is platform independent and can be used on any platform.
Example architectures¶
There are many platforms available today on a market, however supporting them all would be tough task for single person.
Therefore it has been decided to support (for purpose of examples) 2
platforms only, WIN32 and STM32.
WIN32¶
Examples for WIN32 are prepared as Visual Studio Community projects. You can directly open project in the IDE, compile & debug.
To run examples on this architecture, external USB to UART converted would be necessary. Application opens COM port and sends/receives data directly to there.
Tip
Push-pull to open-drain external converter might be necessary. Check Hardware connection with sensor for more information.
STM32¶
Embedded market is supported by many vendors and STMicroelectronics is, with their STM32 series of microcontrollers, one of the most important players. There are numerous amount of examples and topics related to this architecture.
Examples for STM32 are natively supported with STM32CubeIDE, an official development IDE from STMicroelectronics.
You can run examples on one of official development boards, available in repository examples.
Board name |
Onewire settings |
Debug settings |
||||
---|---|---|---|---|---|---|
UART |
MTX |
MRX |
UART |
MDTX |
MDRX |
|
STM32L496G-Discovery |
USART1 |
PB6 |
PG10 |
USART2 |
PA2 |
PD6 |
STM32F429ZI-Nucleo |
USART1 |
PA9 |
PA10 |
USART3 |
PD8 |
PD9 |
Pins to connect to 1-Wire sensor:
MTX: MCU TX pin, connected to 1-Wire network data pin (together with MCU RX pin)
MRX: MCU RX pin, connected to 1-Wire network data pin (together with MCU TX pin)
TX pin is configured as open-drain and can be safely connected directly with RX pin
Other pins are for your information and are used for debugging purposes on board.
MDTX: MCU Debug TX pin, connected via on-board ST-Link to PC
MDRX: MCU Debug RX pin, connected via on-board ST-Link to PC
Baudrate is always set to
921600
bauds
Examples list¶
Here is a list of all examples coming with this library.
Tip
Examples are located in /examples/
folder in downloaded package.
Check Download library section to get your package.
LwOW bare-metal¶
Simple example, not using operating system, showing basic configuration of the library. It can be also called bare-metal implementation for simple applications.