LwOW branch-38c6d63 documentation¶
Welcome to the documentation for version branch-38c6d63.
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 Donate
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¶
Getting started may be the most challenging part of every new library. This guide is describing how to start with the library quickly and effectively
Download library¶
Library is primarly hosted on Github.
You can get it with:
Downloading latest release from releases area on Github
Cloning
master
branch for latest stable versionCloning
develop
branch for latest development
Download from releases¶
All releases are available on Github releases area.
Clone from Github¶
First-time clone¶
This is used when you do not have yet local copy on your machine.
Make sure
git
is installed.Open 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 submodules onmaster
branchRun
git pull origin develop --recurse-submodules
command to pull latest changes and to fetch latest changes from submodules ondevelop
branchRun
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. Next step is to add the library to the project, by means of source files to compiler inputs and header files in search path
Copy
lwow
folder to your project, it contains library filesAdd
lwow/src/include
folder to include path of your toolchain. This is where C/C++ compiler can find the files during compilation process. Usually using-I
flagAdd source files from
lwow/src/
folder to toolchain build. These files are built by C/C++ compilerCopy
lwow/src/include/lwow/lwow_opts_template.h
to project folder and rename it tolwow_opts.h
Build the project
Configuration file¶
Configuration file is used to overwrite default settings defined for the essential use case.
Library comes with template config file, which can be modified according to needs.
and it should be copied (or simply renamed in-place) and named lwow_opts.h
Note
Default configuration template file location: lwow/src/include/lwow/lwow_opts_template.h
.
File must be renamed to lwow_opts.h
first and then copied to the project directory where compiler
include paths have access to it by using #include "lwow_opts.h"
.
List of configuration options are available in the Configuration section. If any option is about to be modified, it should be done in configuration file
1/**
2 * \file lwow_opts_template.h
3 * \brief LwOW application configuration
4 */
5
6/*
7 * Copyright (c) 2020 Tilen MAJERLE
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without restriction,
12 * including without limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 * This file is part of LwOW - Lightweight onewire library.
30 *
31 * Author: Tilen MAJERLE <tilen@majerle.eu>
32 * Version: v3.0.2
33 */
34#ifndef LWOW_HDR_OPTS_H
35#define LWOW_HDR_OPTS_H
36
37/* Rename this file to "lwow_opts.h" for your application */
38
39/*
40 * Open "include/lwow/lwow_opt.h" and
41 * copy & replace here settings you want to change values
42 */
43
44#endif /* LWOW_HDR_OPTS_H */
Note
If you prefer to avoid using configuration file, application must define
a global symbol LWOW_IGNORE_USER_OPTS
, visible across entire application.
This can be achieved with -D
compiler option.
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 manually.
Tip
To enable thread-safety support, parameter LWOW_CFG_OS
must be set to 1
.
Please check 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 * \file lwow_sys_cmsis_os.c
3 * \brief System functions for CMSIS-OS based operating system
4 */
5
6/*
7 * Copyright (c) 2020 Tilen MAJERLE
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without restriction,
12 * including without limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 * This file is part of LwOW - Lightweight onewire library.
30 *
31 * Author: Tilen MAJERLE <tilen@majerle.eu>
32 * Version: v3.0.2
33 */
34#include "lwow/lwow.h"
35
36#if LWOW_CFG_OS && !__DOXYGEN__
37
38#include "cmsis_os.h"
39
40uint8_t
41lwow_sys_mutex_create(LWOW_CFG_OS_MUTEX_HANDLE* m, void* arg) {
42 LWOW_UNUSED(arg);
43 const osMutexAttr_t attr = {
44 .attr_bits = osMutexRecursive,
45 .name = "lwow_mutex",
46 };
47 return (*m = osMutexNew(&attr)) != NULL;
48}
49
50uint8_t
51lwow_sys_mutex_delete(LWOW_CFG_OS_MUTEX_HANDLE* m, void* arg) {
52 LWOW_UNUSED(arg);
53 return osMutexDelete(*m) == osOK;
54}
55
56uint8_t
57lwow_sys_mutex_wait(LWOW_CFG_OS_MUTEX_HANDLE* m, void* arg) {
58 LWOW_UNUSED(arg);
59 return osMutexAcquire(*m, osWaitForever) == osOK;
60}
61
62uint8_t
63lwow_sys_mutex_release(LWOW_CFG_OS_MUTEX_HANDLE* m, void* arg) {
64 LWOW_UNUSED(arg);
65 return osMutexRelease(*m) == osOK;
66}
67
68#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
Push-pull to open-drain converter¶
Since many latest embedded systems allow you to configure TX pin to open-drain mode natively, you may consider second option instead.
Embedded system with native open-drain TX pin support¶
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
UART byte time is equivalent to 1 bit at 1-Wire level¶
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 * \file lwow_ll_win32.c
3 * \brief UART implementation for WIN32
4 */
5
6/*
7 * Copyright (c) 2020 Tilen MAJERLE
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without restriction,
12 * including without limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 * This file is part of LwOW - Lightweight onewire library.
30 *
31 * Author: Tilen MAJERLE <tilen@majerle.eu>
32 * Version: v3.0.2
33 */
34#include <stdio.h>
35#include "lwow/lwow.h"
36#include "windows.h"
37
38#if !__DOXYGEN__
39
40/* Function prototypes */
41static uint8_t init(void* arg);
42static uint8_t deinit(void* arg);
43static uint8_t set_baudrate(uint32_t baud, void* arg);
44static uint8_t transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg);
45
46/* Win 32 LL driver for OW */
47const lwow_ll_drv_t
48lwow_ll_drv_win32 = {
49 .init = init,
50 .deinit = deinit,
51 .set_baudrate = set_baudrate,
52 .tx_rx = transmit_receive,
53};
54
55static HANDLE com_port;
56static DCB dcb = { 0 };
57
58static uint8_t
59init(void* arg) {
60 dcb.DCBlength = sizeof(dcb);
61
62 /* Open virtual file as read/write */
63 com_port = CreateFile(L"\\\\.\\COM4",
64 GENERIC_READ | GENERIC_WRITE,
65 0,
66 0,
67 OPEN_EXISTING,
68 0,
69 NULL
70 );
71
72 /* First read current values */
73 if (GetCommState(com_port, &dcb)) {
74 COMMTIMEOUTS timeouts;
75
76 dcb.BaudRate = 115200;
77 dcb.ByteSize = 8;
78 dcb.Parity = NOPARITY;
79 dcb.StopBits = ONESTOPBIT;
80
81 /* Try to set com port data */
82 if (!SetCommState(com_port, &dcb)) {
83 printf("Cannot get COM port\r\n");
84 return 0;
85 }
86
87 if (GetCommTimeouts(com_port, &timeouts)) {
88 /* Set timeout to return immediatelly from ReadFile function */
89 timeouts.ReadIntervalTimeout = MAXDWORD;
90 timeouts.ReadTotalTimeoutConstant = 0;
91 timeouts.ReadTotalTimeoutMultiplier = 0;
92 if (!SetCommTimeouts(com_port, &timeouts)) {
93 printf("Cannot set COM PORT timeouts\r\n");
94 }
95 GetCommTimeouts(com_port, &timeouts);
96 }
97 } else {
98 printf("Cannot get COM port info\r\n");
99 }
100
101 return 1;
102}
103
104uint8_t
105deinit(void* arg) {
106 /* Disable UART peripheral */
107
108 return 1;
109}
110
111uint8_t
112set_baudrate(uint32_t baud, void* arg) {
113 /* Configure UART to selected baudrate */
114 dcb.BaudRate = baud;
115
116 /* Try to set com port data */
117 if (!SetCommState(com_port, &dcb)) {
118 printf("Cannot set COM port baudrate to %u bauds\r\n", (unsigned)baud);
119 return 0;
120 }
121
122 return 1;
123}
124
125uint8_t
126transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg) {
127 /* Perform data exchange */
128 size_t read = 0;
129 DWORD br;
130
131 if (com_port != NULL) {
132 /*
133 * Flush any data in RX buffer.
134 * This helps to reset communication in case of on-the-fly device management
135 * if one-or-more device(s) are added or removed.
136 *
137 * Any noise on UART level could start byte and put it to Win buffer,
138 * preventing to read aligned data from it
139 */
140 PurgeComm(com_port, PURGE_RXCLEAR | PURGE_RXABORT);
141
142 /* Write file and send data */
143 WriteFile(com_port, tx, len, &br, NULL);
144 FlushFileBuffers(com_port);
145
146 /* Read same amount of data as sent previously (loopback) */
147 do {
148 if (ReadFile(com_port, rx, (DWORD)(len - read), &br, NULL)) {
149 read += (size_t)br;
150 rx += (size_t)br;
151 }
152 } while (read < len);
153 }
154
155 return 1;
156}
157
158#endif /* !__DOXYGEN__ */
Example: Low-level driver for STM32¶
Example code for low-level porting on STM32 platform.
1/**
2 * \file lwow_ll_stm32.c
3 * \brief Generic UART implementation for STM32 MCUs
4 */
5
6/*
7 * Copyright (c) 2020 Tilen MAJERLE
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without restriction,
12 * including without limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 * This file is part of LwOW - Lightweight onewire library.
30 *
31 * Author: Tilen MAJERLE <tilen@majerle.eu>
32 * Version: v3.0.2
33 */
34
35/*
36 * How it works
37 *
38 * https://docs.majerle.eu/projects/lwow/en/latest/user-manual/hw_connection.html#
39 */
40#include "lwow/lwow.h"
41
42#if !__DOXYGEN__
43
44static uint8_t init(void* arg);
45static uint8_t deinit(void* arg);
46static uint8_t set_baudrate(uint32_t baud, void* arg);
47static uint8_t transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg);
48
49/* STM32 LL driver for OW */
50const lwow_ll_drv_t
51lwow_ll_drv_stm32 = {
52 .init = init,
53 .deinit = deinit,
54 .set_baudrate = set_baudrate,
55 .tx_rx = transmit_receive,
56};
57
58static LL_USART_InitTypeDef
59usart_init;
60
61static uint8_t
62init(void* arg) {
63 LL_GPIO_InitTypeDef gpio_init;
64
65 /* Peripheral clock enable */
66 ONEWIRE_USART_CLK_EN;
67 ONEWIRE_TX_PORT_CLK_EN;
68 ONEWIRE_RX_PORT_CLK_EN;
69
70 /* Configure GPIO pins */
71 LL_GPIO_StructInit(&gpio_init);
72 gpio_init.Mode = LL_GPIO_MODE_ALTERNATE;
73 gpio_init.Speed = LL_GPIO_SPEED_FREQ_HIGH;
74 gpio_init.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
75 gpio_init.Pull = LL_GPIO_PULL_UP;
76
77 /* TX pin */
78 gpio_init.Alternate = ONEWIRE_TX_PIN_AF;
79 gpio_init.Pin = ONEWIRE_TX_PIN;
80 LL_GPIO_Init(ONEWIRE_TX_PORT, &gpio_init);
81
82 /* RX pin */
83 gpio_init.Alternate = ONEWIRE_RX_PIN_AF;
84 gpio_init.Pin = ONEWIRE_RX_PIN;
85 LL_GPIO_Init(ONEWIRE_RX_PORT, &gpio_init);
86
87 /* Configure UART peripherals */
88 LL_USART_DeInit(ONEWIRE_USART);
89 LL_USART_StructInit(&usart_init);
90 usart_init.BaudRate = 9600;
91 usart_init.DataWidth = LL_USART_DATAWIDTH_8B;
92 usart_init.StopBits = LL_USART_STOPBITS_1;
93 usart_init.Parity = LL_USART_PARITY_NONE;
94 usart_init.TransferDirection = LL_USART_DIRECTION_TX_RX;
95 usart_init.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
96 usart_init.OverSampling = LL_USART_OVERSAMPLING_16;
97 LL_USART_Init(ONEWIRE_USART, &usart_init);
98 LL_USART_ConfigAsyncMode(ONEWIRE_USART);
99
100 LWOW_UNUSED(arg);
101
102 return 1;
103}
104
105static uint8_t
106deinit(void* arg) {
107 LL_USART_DeInit(ONEWIRE_USART);
108 LWOW_UNUSED(arg);
109 return 1;
110}
111
112static uint8_t
113set_baudrate(uint32_t baud, void* arg) {
114 usart_init.BaudRate = baud;
115 LL_USART_Init(ONEWIRE_USART, &usart_init);
116 LL_USART_ConfigAsyncMode(ONEWIRE_USART);
117 LWOW_UNUSED(arg);
118
119 return 1;
120}
121
122static uint8_t
123transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg) {
124 const uint8_t* t = tx;
125 uint8_t* r = rx;
126
127 /* Send byte with polling */
128 LL_USART_Enable(ONEWIRE_USART);
129 for (; len > 0; --len, ++t, ++r) {
130 LL_USART_TransmitData8(ONEWIRE_USART, *t);
131 while (!LL_USART_IsActiveFlag_TXE(ONEWIRE_USART));
132 while (!LL_USART_IsActiveFlag_RXNE(ONEWIRE_USART));
133 *r = LL_USART_ReceiveData8(ONEWIRE_USART);
134 }
135 while (!LL_USART_IsActiveFlag_TC(ONEWIRE_USART)) {}
136 LL_USART_Disable(ONEWIRE_USART);
137 LWOW_UNUSED(arg);
138 return 1;
139}
140
141#endif /* !__DOXYGEN__ */
Example: System functions for WIN32¶
1/**
2 * \file lwow_sys_win32.c
3 * \brief System functions for WIN32
4 */
5
6/*
7 * Copyright (c) 2020 Tilen MAJERLE
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without restriction,
12 * including without limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 * This file is part of LwOW - Lightweight onewire library.
30 *
31 * Author: Tilen MAJERLE <tilen@majerle.eu>
32 * Version: v3.0.2
33 */
34#include "lwow/lwow.h"
35#include "windows.h"
36
37#if LWOW_CFG_OS && !__DOXYGEN__
38
39uint8_t
40lwow_sys_mutex_create(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
41 *mutex = CreateMutex(NULL, 0, NULL);
42 return 1;
43}
44
45uint8_t
46lwow_sys_mutex_delete(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
47 CloseHandle(*mutex);
48 *mutex = NULL;
49 return 1;
50}
51
52uint8_t
53lwow_sys_mutex_wait(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
54 return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0;
55}
56
57uint8_t
58lwow_sys_mutex_release(LWOW_CFG_OS_MUTEX_HANDLE* mutex, void* arg) {
59 return ReleaseMutex(*mutex);
60}
61
62#endif /* LWOW_CFG_OS && !__DOXYGEN__ */
Example: System functions for CMSIS-OS¶
1/**
2 * \file lwow_sys_cmsis_os.c
3 * \brief System functions for CMSIS-OS based operating system
4 */
5
6/*
7 * Copyright (c) 2020 Tilen MAJERLE
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without restriction,
12 * including without limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 * This file is part of LwOW - Lightweight onewire library.
30 *
31 * Author: Tilen MAJERLE <tilen@majerle.eu>
32 * Version: v3.0.2
33 */
34#include "lwow/lwow.h"
35
36#if LWOW_CFG_OS && !__DOXYGEN__
37
38#include "cmsis_os.h"
39
40uint8_t
41lwow_sys_mutex_create(LWOW_CFG_OS_MUTEX_HANDLE* m, void* arg) {
42 LWOW_UNUSED(arg);
43 const osMutexAttr_t attr = {
44 .attr_bits = osMutexRecursive,
45 .name = "lwow_mutex",
46 };
47 return (*m = osMutexNew(&attr)) != NULL;
48}
49
50uint8_t
51lwow_sys_mutex_delete(LWOW_CFG_OS_MUTEX_HANDLE* m, void* arg) {
52 LWOW_UNUSED(arg);
53 return osMutexDelete(*m) == osOK;
54}
55
56uint8_t
57lwow_sys_mutex_wait(LWOW_CFG_OS_MUTEX_HANDLE* m, void* arg) {
58 LWOW_UNUSED(arg);
59 return osMutexAcquire(*m, osWaitForever) == osOK;
60}
61
62uint8_t
63lwow_sys_mutex_release(LWOW_CFG_OS_MUTEX_HANDLE* m, void* arg) {
64 LWOW_UNUSED(arg);
65 return osMutexRelease(*m) == osOK;
66}
67
68#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 * \file lwow_ll_stm32_hal.c
3 * \brief UART driver implementation for STM32 with HAL code
4 */
5
6/*
7 * Copyright (c) 2020 Tilen MAJERLE
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without restriction,
12 * including without limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 * This file is part of LwOW - Lightweight onewire library.
30 *
31 * Author: Tilen MAJERLE <tilen@majerle.eu>
32 * Version: v3.0.2
33 */
34
35/*
36 * How it works (general)
37 *
38 * https://docs.majerle.eu/projects/lwow/en/latest/user-manual/hw_connection.html#
39 *
40 * This specific driver is optimized for proejcts generated by STM32CubeMX or STM32CubeIDE with HAL drivers
41 * It can be used w/ or w/o operating system and it uses interrupts & polling for data receive and data transmit.
42 *
43 * Application must pass pointer to UART handle as argument to ow_init function in order
44 * to link OW instance with actual UART hardware used for OW instance.
45 *
46 * To use this driver, application must:
47 * - Enable interrupt in CubeMX to allow HAL_UART_Receive_IT functionality
48 * - Use pointer to UART handle when initializing ow with ow_init
49 */
50#include "lwow/lwow.h"
51#include "main.h" /* Generated normally by CubeMX */
52
53#if !__DOXYGEN__
54
55static uint8_t init(void* arg);
56static uint8_t deinit(void* arg);
57static uint8_t set_baudrate(uint32_t baud, void* arg);
58static uint8_t transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg);
59
60/* STM32 LL driver for OW */
61const lwow_ll_drv_t
62lwow_ll_drv_stm32_hal = {
63 .init = init,
64 .deinit = deinit,
65 .set_baudrate = set_baudrate,
66 .tx_rx = transmit_receive,
67};
68
69static uint8_t
70init(void* arg) {
71 UART_HandleTypeDef* huart = arg;
72
73 LWOW_ASSERT0("arg != NULL", arg != NULL);
74
75 /* Initialize UART */
76 HAL_UART_DeInit(huart);
77 return HAL_UART_Init(huart) == HAL_OK;
78}
79
80static uint8_t
81deinit(void* arg) {
82 UART_HandleTypeDef* huart = arg;
83
84 LWOW_ASSERT0("arg != NULL", arg != NULL);
85
86 return HAL_UART_DeInit(huart);
87}
88
89static uint8_t
90set_baudrate(uint32_t baud, void* arg) {
91 UART_HandleTypeDef* huart = arg;
92
93 LWOW_ASSERT0("arg != NULL", arg != NULL);
94
95 huart->Init.BaudRate = baud;
96 return init(huart);
97}
98
99static uint8_t
100transmit_receive(const uint8_t* tx, uint8_t* rx, size_t len, void* arg) {
101 UART_HandleTypeDef* huart = arg;
102 uint32_t start;
103
104 LWOW_ASSERT0("arg != NULL", arg != NULL);
105
106 /* Get current HAL tick */
107 start = HAL_GetTick();
108
109 /* Start RX in interrupt mode */
110 HAL_UART_Receive_IT(huart, rx, len);
111
112 /* Process TX in polling mode */
113 HAL_UART_Transmit(huart, (void*)tx, len, 100);
114
115 /* Wait RX to finish */
116 while (huart->RxState != HAL_UART_STATE_READY) {
117 if (HAL_GetTick() - start > 100) {
118 return 0;
119 }
120 }
121
122 return 1;
123}
124
125#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
msg – [in] Optional message parameter to print on failure
c – [in] Condition to check for
-
LWOW_ASSERT0(msg, c)¶
Assert check function with return
0
It returns
0
if condition check fails- Parameters
msg – [in] Optional message parameter to print on failure
c – [in] Condition to check for
-
LWOW_ARRAYSIZE(x)¶
Get size of statically declared array.
- Parameters
x – [in] Input array
- Returns
Number of array elements
-
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.
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] Rom address when new device detected. Set to
NULL
when search finishedindex – [in] Current device index When
rom_id = NULL
, value indicates number of total devices foundarg – [in] Custom user argument
- Returns
Enums
-
enum lwowr_t¶
1-Wire result enumeration
Values:
-
enumerator lwowOK¶
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 lwowOK¶
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
ow – [in] OneWire instance
-
lwowr_t lwow_protect(lwow_t *const ow, const uint8_t protect)¶
Protect 1-wire from concurrent access.
Note
Used only for OS systems
-
lwowr_t lwow_unprotect(lwow_t *const ow, const uint8_t protect)¶
Unprotect 1-wire from concurrent access.
Note
Used only for OS systems
-
lwowr_t lwow_reset(lwow_t *const ow)¶
Reset 1-Wire bus and set connected devices to idle state.
Note
This function is thread-safe
-
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.
Note
This function is thread-safe
-
lwowr_t lwow_read_byte_ex(lwow_t *const ow, uint8_t *const br)¶
Read byte from OW device.
Note
This function is thread-safe
-
lwowr_t lwow_read_bit_ex(lwow_t *const ow, uint8_t *const br)¶
Read sinle bit from OW device.
Note
This function is thread-safe
-
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
-
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
Note
This function is thread-safe
-
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
-
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
Note
This function is thread-safe
-
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 userNote
This function is thread-safe
- Parameters
ow – [in] 1-Wire handle
cmd – [in] 1-Wire search command
roms_found – [out] Output variable to save number of found devices. Set to
NULL
if not usedfunc – [in] Callback function to call for each device
arg – [in] Custom user argument, used in callback function
- Returns
-
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 userNote
This function is thread-safe
-
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.
- Parameters
ow – [in] 1-Wire handle
cmd – [in] 1-Wire search command
rom_id_arr – [in] Pointer to output array to store found ROM IDs into
rom_len – [in] Length of input ROM array
roms_found – [out] Output variable to save number of found devices. Set to
NULL
if not used
- Returns
-
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.
Note
This function is thread-safe
- Parameters
ow – [in] 1-Wire handle
cmd – [in] 1-Wire search command
rom_id_arr – [in] Pointer to output array to store found ROM IDs into
rom_len – [in] Length of input ROM array
roms_found – [out] Output variable to save number of found devices. Set to
NULL
if not used
- Returns
-
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.
Note
This function is thread-safe
-
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.
Note
This function is thread-safe
-
lwowr_t lwow_skip_rom_raw(lwow_t *const ow)¶
Skip ROM address and select all devices on the network.
-
lwowr_t lwow_skip_rom(lwow_t *const ow)¶
Skip ROM address and select all devices on the network.
Note
This function is thread-safe
-
uint8_t lwow_crc(const void *const in, const size_t len)¶
Calculate CRC-8 of input data.
Note
This function is reentrant
- Parameters
in – [in] Input data
len – [in] Number of bytes
- Returns
Calculated CRC
-
uint8_t lwow_write_byte_raw(lwow_t *const ow, const uint8_t b)¶
Write byte over 1-wire protocol.
- Deprecated:
This function is deprecated. Use lwow_write_byte_ex_raw instead
Note
This function is deprecated. Use lwow_write_byte_ex_raw instead
- Parameters
ow – [inout] 1-Wire handle
b – [in] Byte to write
- Returns
Received byte over 1-wire protocol
-
uint8_t lwow_write_byte(lwow_t *const ow, const uint8_t b)¶
Write byte over 1-wire protocol.
- Deprecated:
This function is deprecated. Use lwow_write_byte_ex_raw instead
- Deprecated:
This function is deprecated. Use lwow_write_byte_ex instead
Note
This function is deprecated. Use lwow_write_byte_ex_raw instead
Note
This function is deprecated. Use lwow_write_byte_ex instead
Note
This function is thread-safe
- Parameters
ow – [inout] 1-Wire handle
b – [in] Byte to write
- Returns
Received byte over 1-wire protocol
-
uint8_t lwow_read_byte_raw(lwow_t *const ow)¶
Read next byte on 1-Wire.
- Deprecated:
This function is deprecated. Use lwow_read_byte_ex_raw instead
Note
This function is deprecated. Use lwow_read_byte_ex_raw instead
- Parameters
ow – [inout] 1-Wire handle
- Returns
Byte read over 1-Wire
-
uint8_t lwow_read_byte(lwow_t *const ow)¶
Read next byte on 1-Wire.
- Deprecated:
This function is deprecated. Use lwow_read_byte_ex_raw instead
- Deprecated:
This function is deprecated. Use lwow_read_byte_ex instead
Note
This function is deprecated. Use lwow_read_byte_ex_raw instead
Note
This function is deprecated. Use lwow_read_byte_ex instead
Note
This function is thread-safe
- Parameters
ow – [inout] 1-Wire handle
- Returns
Byte read over 1-Wire
-
uint8_t lwow_read_bit_raw(lwow_t *const ow)¶
Read single bit on 1-Wire network.
- Deprecated:
This function is deprecated. Use lwow_read_bit_ex_raw instead
Note
This function is deprecated. Use lwow_read_bit_ex_raw instead
- Parameters
ow – [inout] 1-Wire handle
- Returns
Bit value
-
uint8_t lwow_read_bit(lwow_t *const ow)¶
Read single bit on 1-Wire network.
- Deprecated:
This function is deprecated. Use lwow_read_bit_ex_raw instead
- Deprecated:
This function is deprecated. Use lwow_read_bit_ex instead
Note
This function is deprecated. Use lwow_read_bit_ex_raw instead
Note
This function is deprecated. Use lwow_read_bit_ex instead
Note
This function is thread-safe
- Parameters
ow – [inout] 1-Wire handle
- Returns
Bit value
-
struct lwow_rom_t¶
- #include <lwow.h>
ROM structure.
Public Members
-
uint8_t rom[8]¶
8-bytes ROM address
-
uint8_t rom[8]¶
-
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 rom¶
-
LWOW_UNUSED(x)¶
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 for guidelines on how to create and use 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
-
LWOW_CFG_OS¶
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.
- Parameters
arg – [in] Custom argument passed to lwow_init function
- Returns
1
on success,0
otherwise
-
uint8_t (*deinit)(void *arg)¶
De-initialize low-level driver.
- Parameters
arg – [in] Custom argument passed to lwow_init function
- Returns
1
on success,0
otherwise
-
uint8_t (*set_baudrate)(uint32_t baud, void *arg)¶
Set UART baudrate.
- Parameters
baud – [in] Baudrate to set in units of bauds, normally
9600
or115200
arg – [in] Custom argument passed to lwow_init function
- Returns
1
on success,0
otherwise
-
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- Parameters
tx – [in] Data to transmit over UART
rx – [out] Array to write received data to
len – [in] Number of bytes to exchange
arg – [in] Custom argument passed to lwow_init function
- Returns
1
on success,0
otherwise
-
uint8_t (*init)(void *arg)¶
-
struct lwow_ll_drv_t¶
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.
- Parameters
mutex – [out] Output variable to save mutex handle
arg – [in] User argument passed on lwow_init function
- Returns
1
on success,0
otherwise
-
uint8_t lwow_sys_mutex_delete(LWOW_CFG_OS_MUTEX_HANDLE *mutex, void *arg)¶
Delete existing mutex and invalidate mutex variable.
- Parameters
mutex – [in] Mutex handle to remove and invalidate
arg – [in] User argument passed on lwow_init function
- Returns
1
on success,0
otherwise
-
uint8_t lwow_sys_mutex_create(LWOW_CFG_OS_MUTEX_HANDLE *mutex, void *arg)¶
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.
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to start measurement for. Set to
NULL
to start measurement on all devices at the same time
- Returns
1
on success,0
otherwise
-
uint8_t lwow_ds18x20_start(lwow_t *const ow, const lwow_rom_t *const rom_id)¶
Start temperature conversion on specific (or all) devices.
Note
This function is thread-safe
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to start measurement for. Set to
NULL
to start measurement on all devices at the same time
- Returns
1
on success,0
otherwise
-
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.
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to read data from
t – [out] Pointer to output float variable to save temperature
- Returns
1
on success,0
otherwise
-
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.
Note
This function is thread-safe
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to read data from
t – [out] Pointer to output float variable to save temperature
- Returns
1
on success,0
otherwise
-
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- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to set resolution
bits – [in] Number of resolution bits. Possible values are
9 - 12
- Returns
1
on success,0
otherwise
-
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
resolutionNote
This function is thread-safe
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to set resolution
bits – [in] Number of resolution bits. Possible values are
9 - 12
- Returns
1
on success,0
otherwise
-
uint8_t lwow_ds18x20_get_resolution_raw(lwow_t *const ow, const lwow_rom_t *const rom_id)¶
Get resolution for
DS18B20
device.- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to get resolution from
- Returns
Resolution in units of bits (
9 - 12
) on success,0
otherwise
-
uint8_t lwow_ds18x20_get_resolution(lwow_t *const ow, const lwow_rom_t *const rom_id)¶
Get resolution for
DS18B20
device.Note
This function is thread-safe
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to get resolution from
- Returns
Resolution in units of bits (
9 - 12
) on success,0
otherwise
-
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)
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address
temp_l – [in] Alarm low temperature
temp_h – [in] Alarm high temperature
- Returns
1
on success,0
otherwise
-
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)
Note
This function is thread-safe
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address
temp_l – [in] Alarm low temperature
temp_h – [in] Alarm high temperature
- Returns
1
on success,0
otherwise
-
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
-
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
Note
This function is thread-safe
-
uint8_t lwow_ds18x20_is_b(lwow_t *const ow, const lwow_rom_t *const rom_id)¶
Check if ROM address matches
DS18B20
device.Note
This function is reentrant
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to test against
DS18B20
- Returns
1
on success,0
otherwise
-
uint8_t lwow_ds18x20_is_s(lwow_t *const ow, const lwow_rom_t *const rom_id)¶
Check if ROM address matches
DS18S20
device.Note
This function is reentrant
- Parameters
ow – [in] 1-Wire handle
rom_id – [in] 1-Wire device address to test against
DS18S20
- Returns
1
on success,0
otherwise
-
LWOW_DS18X20_ALARM_DISABLE¶
Examples and demos¶
Various examples are provided for fast library evaluation on embedded systems. These are 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.