@@ -0,0 +1,55 @@ | |||
# Copyright 2021 John-Mark Gurney. | |||
# | |||
# Redistribution and use in source and binary forms, with or without | |||
# modification, are permitted provided that the following conditions | |||
# are met: | |||
# 1. Redistributions of source code must retain the above copyright | |||
# notice, this list of conditions and the following disclaimer. | |||
# 2. Redistributions in binary form must reproduce the above copyright | |||
# notice, this list of conditions and the following disclaimer in the | |||
# documentation and/or other materials provided with the distribution. | |||
# | |||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
# SUCH DAMAGE. | |||
# | |||
.if $(.OBJDIR) == $(.CURDIR) | |||
.error Need to set MAKEOBJDIR. | |||
.endif | |||
PLATFORM != uname -s | |||
.if $(PLATFORM) == "Darwin" | |||
SOEXT=dylib | |||
.else | |||
.error Unsupported platform: $(PLATFORM) | |||
.endif | |||
PROGS = blinkled | |||
SRCS.blinkled = main.c | |||
SRCS.blinkled+= $(SRCTOP)/rs485hid/memdebug.c | |||
SRCS.blinkled+= stm32f1xx_hal_tim.c | |||
SRCS.blinkled+= stm32f1xx_hal_tim_ex.c | |||
CFLAGS+= -I$(.CURDIR) | |||
CFLAGS+= -g | |||
CFLAGS+= -DHAL_TIM_MODULE_ENABLED=1 | |||
#CFLAGS+= -DNDEBUG | |||
WITH_STM32F103 = yes | |||
.include <../mk/boards.mk> | |||
CFLAGS+= -Werror -Wall | |||
.include <../mk/mu.progs.mk> |
@@ -0,0 +1,24 @@ | |||
Blink LED | |||
========= | |||
This project is to blink a LED, and have a standard cell phone camera | |||
decode the data. | |||
8b10b code | |||
---------- | |||
Adding: | |||
``` | |||
(cd ..; git subtree add -P blinkled/encdec8b10b --squash https://github.com/olagrottvik/encdec8b10b.git master) | |||
``` | |||
Updating: | |||
``` | |||
(cd ..; git subtree pull -P blinkled/encdec8b10b --squash https://github.com/olagrottvik/encdec8b10b.git master) | |||
``` | |||
Info | |||
---- | |||
[8b/10b encoding](https://en.wikipedia.org/wiki/8b/10b_encoding) |
@@ -0,0 +1,6 @@ | |||
.idea | |||
__pycache__ | |||
build/ | |||
venv/ | |||
dist/ | |||
*egg-info* |
@@ -0,0 +1,9 @@ | |||
language: python | |||
python: | |||
- "3.4" | |||
- "3.5" | |||
- "3.6" | |||
install: | |||
- pip install -e . | |||
script: | |||
- make test |
@@ -0,0 +1,21 @@ | |||
MIT License | |||
Copyright (c) 2019 Ola Grøttvik | |||
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. |
@@ -0,0 +1,26 @@ | |||
.PHONY: init freeze test test_verbose build_dist upload | |||
venv: | |||
python3 -m venv .env | |||
init: | |||
pip install -r requirements.txt | |||
freeze: | |||
pip freeze | grep -v "pkg-resources" > requirements.txt | |||
test: | |||
nosetests tests/* | |||
test_verbose: | |||
nosetests --nocapture tests/* | |||
build_dist: | |||
rm -rf dist/* | |||
python3 setup.py sdist bdist_wheel | |||
upload_test: | |||
python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/* | |||
upload: | |||
python3 -m twine upload dist/* |
@@ -0,0 +1,88 @@ | |||
[![Build Status](https://travis-ci.com/olagrottvik/encdec8b10b.svg?token=jVu3gMDvjaqfNCVgNVai&branch=master)](https://travis-ci.com/olagrottvik/encdec8b10b) | |||
# encdec8b10b | |||
Encode and decode 8B10B encoding | |||
## Get | |||
``` | |||
python3 -m pip install encdec8b10b | |||
``` | |||
## Usage | |||
### Encode Data Byte | |||
``` | |||
from encdec8b10b import EncDec8B10B | |||
running_disp = 0 | |||
byte_to_enc = 0xf | |||
running_disp, encoded = EncDec8B10B.enc_8b10b(byte_to_enc, running_disp) | |||
print(hex(encoded)) | |||
Output >> 0xba | |||
``` | |||
### Encode Control Byte | |||
``` | |||
from encdec8b10b import EncDec8B10B | |||
running_disp = 0 | |||
byte_to_enc = 0xbc # comma | |||
ctrl = 1 | |||
running_disp, encoded = EncDec8B10B.enc_8b10b(byte_to_enc, running_disp, ctrl) | |||
print(hex(encoded)) | |||
Output >> 0x17c | |||
``` | |||
### Decode Data Byte | |||
``` | |||
from encdec8b10b import EncDec8B10B | |||
byte_to_dec = 0xba | |||
ctrl, decoded = EncDec8B10B.dec_8b10b(byte_to_dec) | |||
print(hex(decoded)) | |||
Output >> 0xf | |||
# ctrl variable confirm that it was a data byte | |||
print(ctrl) | |||
Output >> 0 | |||
``` | |||
### Decode Control Byte | |||
``` | |||
from encdec8b10b import EncDec8B10B | |||
byte_to_dec = 0x17c # comma encoded | |||
ctrl, decoded = EncDec8B10B.dec_8b10b(byte_to_dec) | |||
print(hex(decoded)) | |||
Output >> 0xbc | |||
# ctrl variable confirm that it was a control byte | |||
print(ctrl) | |||
Output >> 1 | |||
``` | |||
### Verbosity | |||
Both functions have a verbose-mode to make it easier to confirm everything that's happening: | |||
``` | |||
from encdec8b10b import EncDec8B10B | |||
running_disp = 0 | |||
byte_to_enc = 0xA0 | |||
running_disp, encoded = EncDec8B10B.enc_8b10b(byte_to_enc, running_disp, verbose=True) | |||
Output >> Encoder - In: A0 - Encoded: 146 - Running Disparity: 0 | |||
ctrl, decoded = EncDec8B10B.dec_8b10b(encoded, verbose=True) | |||
Output >> Decoded: A0 - Control: 0 | |||
``` | |||
## 8B10B | |||
8B10B Encoding were implemented by Al Widmer and Peter Franaszek in 1983. It is still widely used in high-speed electronics. | |||
- [Original article](https://ieeexplore.ieee.org/document/5390392) | |||
- [Wikipedia](https://en.wikipedia.org/wiki/8b/10b_encoding) | |||
### Thanks | |||
- [Ryu Shinhyung](https://opencores.org/projects/async_8b10b_encoder_decoder) for creating the tables used in this module | |||
- [Chuck Benz](http://asics.chuckbenz.com/) for creating awesome combinational 8B10B modules | |||
- [Alex Forencich](http://www.alexforencich.com/wiki/en/scripts/matlab/enc8b10b) for his 8B10B Matlab script |
@@ -0,0 +1 @@ | |||
from .core import EncDec8B10B as EncDec8B10B |
@@ -0,0 +1,16 @@ | |||
bleach==3.1.4 | |||
certifi==2019.3.9 | |||
chardet==3.0.4 | |||
docutils==0.14 | |||
idna==2.8 | |||
nose==1.3.7 | |||
pkginfo==1.5.0.1 | |||
Pygments==2.3.1 | |||
readme-renderer==24.0 | |||
requests==2.21.0 | |||
requests-toolbelt==0.9.1 | |||
six==1.12.0 | |||
tqdm==4.31.1 | |||
twine==1.13.0 | |||
urllib3==1.24.2 | |||
webencodings==0.5.1 |
@@ -0,0 +1,17 @@ | |||
import setuptools | |||
with open("README.md", "r") as fh: | |||
long_description = fh.read() | |||
setuptools.setup( | |||
name='encdec8b10b', | |||
version='1.0', | |||
packages=setuptools.find_packages(), | |||
url='https://github.com/olagrottvik/encdec8b10b', | |||
license='MIT', | |||
author='Ola Grøttvik', | |||
author_email='olagrottvik@gmail.com', | |||
description='8B10B Encoding and Decoding', | |||
long_description=long_description, | |||
long_description_content_type="text/markdown", | |||
) |
@@ -0,0 +1,7 @@ | |||
# -*- coding: utf-8 -*- | |||
import sys | |||
import os | |||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) | |||
import encdec8b10b |
@@ -0,0 +1,110 @@ | |||
# -*- coding: utf-8 -*- | |||
from .context import encdec8b10b | |||
from encdec8b10b import EncDec8B10B | |||
import random | |||
import unittest | |||
import sys | |||
if sys.version_info.major != 3: | |||
raise RuntimeError('invalid major version of python') | |||
class TestClass(unittest.TestCase): | |||
def test_to10b(self): | |||
to10b = EncDec8B10B._to10b | |||
self.assertEqual(to10b(0), '0' * 10) | |||
self.assertEqual(to10b(2**10-1), '1' * 10) | |||
self.assertEqual(to10b(0x20f), '1' * 4 + '000001') | |||
self.assertEqual(to10b(0x0ff), '1' * 8 + '00') | |||
dispminmax = [ 2, 3, 2, 3, 2, 1, 2, 1, 2, 1 ] | |||
def test_disparity(self): | |||
failures = [] | |||
for i in range(512): | |||
disp = i >> 8 | |||
din = i & 0xff | |||
ndisp, out = EncDec8B10B.enc_8b10b(din, disp) | |||
cnt = +1 if disp else -1 | |||
for j in range(10): | |||
out, bit = divmod(out, 2) | |||
cnt += +1 if bit else -1 | |||
minmax = self.dispminmax[j] | |||
if cnt < -minmax or cnt > minmax: | |||
failures.append((disp, din)) | |||
if cnt != 1 if ndisp else cnt != -1: | |||
failures.append((disp, din)) | |||
if failures: | |||
raise RuntimeError('failures(%d): %s' % (len(failures), repr(failures))) | |||
def test_bitdecoding(self): | |||
coder = EncDec8B10B() | |||
with self.assertRaises(ValueError): | |||
coder.decode('asioj') | |||
self.assertIsNone(coder.decode('')) | |||
self.assertFalse(coder.issyncd()) | |||
self.assertIsNone(coder.decode('101011011010101101')) | |||
self.assertFalse(coder.issyncd()) | |||
self.assertEqual(coder.decode(coder.encode(EncDec8B10B.COMMA)), EncDec8B10B.COMMA) | |||
self.assertTrue(coder.issyncd()) | |||
astr = coder.encode(b'a') | |||
self.assertIsNone(coder.decode(astr[:5])) | |||
self.assertEqual(coder.decode(astr[5:]), b'a') | |||
self.assertEqual(coder.decode(coder.encode(b'abc123')), b'abc123') | |||
chrctrlstr = coder.encode(b'xx') + coder.encode(EncDec8B10B.K_28_0) | |||
self.assertIsNone(coder.decode(chrctrlstr[:5])) | |||
self.assertEqual(coder.decode(chrctrlstr[5:]), b'xx') | |||
self.assertEqual(coder.decode(''), EncDec8B10B.K_28_0) | |||
self.assertEqual(coder.decode(coder.encode(EncDec8B10B.K_28_2)), EncDec8B10B.K_28_2) | |||
# that when junk is delivered, it is ignored | |||
self.assertIsNone(coder.decode('111111111000011111')) | |||
# and is no longer synced | |||
self.assertFalse(coder.issyncd()) | |||
commaastr = coder.encode(EncDec8B10B.COMMA) + \ | |||
coder.encode(b'a') | |||
# But it will sync back up | |||
self.assertEqual(coder.decode(commaastr), EncDec8B10B.COMMA) | |||
self.assertEqual(coder.decode(''), b'a') | |||
self.assertIsNone(coder.decode('')) | |||
self.assertEqual(coder.decode(coder.encode(EncDec8B10B.COMMA)), EncDec8B10B.COMMA) | |||
def test_bitencoding(self): | |||
coder = EncDec8B10B() | |||
self.assertEqual(coder.encode(b'a'), '0111010011') | |||
# + | |||
s = ''.join(( | |||
'1000101100', # a - | |||
'1011010011', # b + | |||
'1100010011', # c + | |||
'1000111001', # 1 + | |||
'0100111001', # 2 + | |||
'1100101001', # 3 + | |||
)) | |||
self.assertEqual(coder.encode(b'abc123'), s) | |||
self.assertEqual(coder.encode(EncDec8B10B.COMMA), '1100000101') | |||
self.assertEqual(coder.encode(EncDec8B10B.COMMA), '0011111010') |
@@ -0,0 +1,87 @@ | |||
# -*- coding: utf-8 -*- | |||
from .context import encdec8b10b | |||
from encdec8b10b import EncDec8B10B | |||
import random | |||
import unittest | |||
verbose = True # Set to True to get test output | |||
class TestSuite(unittest.TestCase): | |||
"""All test cases""" | |||
def test_comma(self): | |||
print("Testing K28.5 Comma...") | |||
running_disparity = 0 | |||
test_data = 0xBC | |||
test_ctrl = 1 | |||
running_disparity, data_encoded = EncDec8B10B.enc_8b10b(test_data, running_disparity, test_ctrl, verbose) | |||
ctrl, data_decoded = EncDec8B10B.dec_8b10b(data_encoded, verbose) | |||
running_disparity, data_encoded = EncDec8B10B.enc_8b10b(data_decoded, running_disparity, 1, verbose) | |||
ctrl, data_decoded = EncDec8B10B.dec_8b10b(data_encoded, verbose) | |||
assert data_decoded == test_data and ctrl == test_ctrl, "K28.5 Comma Test Failed" | |||
def test_known_seq(self): | |||
print("Testing Known Sequence...") | |||
known_seq = [0xa0, 0x7a, 0xFF, 0xc2, 0x48, 0xda, 0x1b, 0x2e, 0x1f, 0x5b, 0xa5, 0x20, 0xb6, 0x10, 0xc3, 0x4d, 0xa0, 0x17, 0x83, | |||
0x3b, 0x2e, 0x7d, 0x61, 0x73, 0x4d, 0xc5, 0x42, 0x59, 0x45, 0x7c, 0x12, 0x1c, 0x03, 0x52, 0xdd, 0x30, 0xa5] | |||
encoded_seq = [0x146, 0xda, 0x235, 0x1ad, 0x298, 0x19a, 0x9b, 0x24e, 0xb5, 0x29b, 0x165, 0x246, 0x156, 0xb6, 0x1a3, 0x28d, 0x179, 0x368, 0x123, | |||
0x25b, 0x24e, 0xe2, 0x32e, 0x313, 0x28d, 0x1a5, 0x292, 0x299, 0x2a5, 0x0dc, 0x372, 0x9c, 0x363, 0x2b2, 0x1a2, 0x276, 0x165] | |||
result_encoded = list() | |||
result_decoded = list() | |||
# Manually set running disparity to known start | |||
running_disparity = 1 | |||
test_ctrl = 0 | |||
for byte, encoded in zip(known_seq, encoded_seq): | |||
running_disparity, data_encoded = EncDec8B10B.enc_8b10b(byte, running_disparity, test_ctrl, verbose) | |||
assert data_encoded == encoded, "Data Encoded (0x{:03X}) does not match known sequence (0x{:03X})".format(data_encoded, encoded) | |||
ctrl, data_decoded = EncDec8B10B.dec_8b10b(data_encoded, verbose) | |||
assert data_decoded == byte, "Data Decoded (0x{:02X}) does not match input byte (0x{:02X})".format(data_decoded, byte) | |||
def test_rand_seq(self): | |||
print("Testing Random Data Sequence...") | |||
test_ctrl = 0 | |||
running_disparity = 0 | |||
for i in range(100000): | |||
rand_byte = random.randint(0, 0xFF) | |||
running_disparity, data_encoded = EncDec8B10B.enc_8b10b(rand_byte, running_disparity, test_ctrl, verbose) | |||
ctrl, data_decoded = EncDec8B10B.dec_8b10b(data_encoded, verbose) | |||
assert rand_byte == data_decoded, "Data Decoded (0x{:02X}) does not match input byte (0x{:02X})".format(data_decoded, rand_byte) | |||
running_disparity = 1 | |||
for i in range(100000): | |||
rand_byte = random.randint(0, 0xFF) | |||
running_disparity, data_encoded = EncDec8B10B.enc_8b10b(rand_byte, running_disparity, test_ctrl, verbose) | |||
ctrl, data_decoded = EncDec8B10B.dec_8b10b(data_encoded, verbose) | |||
assert rand_byte == data_decoded, "Data Decoded (0x{:02X}) does not match input byte (0x{:02X})".format(data_decoded, rand_byte) | |||
def test_ctrl_symbol(self): | |||
print("Testing All Control symbols...") | |||
test_ctrl = 1 | |||
ctrl_symbols = [0x1c, 0x3c, 0x5c, 0x7c, 0x9c, | |||
0xbc, 0xdc, 0xfc, 0xf7, 0xfb, 0xfd, 0xfe] | |||
running_disparity = 0 | |||
for symbol in ctrl_symbols: | |||
running_disparity, data_encoded = EncDec8B10B.enc_8b10b( | |||
symbol, running_disparity, test_ctrl, verbose) | |||
ctrl, data_decoded = EncDec8B10B.dec_8b10b(data_encoded, verbose) | |||
assert symbol == data_decoded, "Data Decoded (0x{:02X}) does not match input byte (0x{:02X})".format( | |||
data_decoded, symbol) | |||
running_disparity = 1 | |||
for symbol in ctrl_symbols: | |||
running_disparity, data_encoded = EncDec8B10B.enc_8b10b(symbol, running_disparity, test_ctrl, verbose) | |||
ctrl, data_decoded = EncDec8B10B.dec_8b10b(data_encoded, verbose) | |||
assert symbol == data_decoded, "Data Decoded (0x{:02X}) does not match input byte (0x{:02X})".format(data_decoded, symbol) | |||
if __name__ == '__main__': | |||
unittest.main() |
@@ -0,0 +1,82 @@ | |||
from encdec8b10b import EncDec8B10B | |||
a = b'Hello, this is a test of encoding.' | |||
coder = EncDec8B10B() | |||
encoded = coder.encode(EncDec8B10B.COMMA) + coder.encode(a) | |||
print('8b10b encoded:', repr(encoded)) | |||
decoder = EncDec8B10B() | |||
print(repr(decoder.decode(encoded))) | |||
print('test decode:', repr(decoder.decode(''))) | |||
def jm3coder(bits, lastlvl=0): | |||
'''Takes in a string of bits, and outputs a trinary level. | |||
It is guaranteed that no two outputs repeat allowing for | |||
easy clock recovery as long as the sampling rate is faster | |||
than output rate. (e.g. 30Hz (33.3ms) sampling of a 29Hz | |||
(34.5ms) signal. | |||
Note that this does not do sync, so something like an 8b10b | |||
encoder should be used on top of this, and then transmit three | |||
dummy bits at the begining as the decoder. The three will | |||
cycle through all three states help ensuring level detection | |||
An optional paramter of lastlvl can be provided, which is | |||
the previous signal level transmitted.''' | |||
r = [] | |||
for i in bits: | |||
v = int(i, 2) | |||
lastlvl = (lastlvl + 1 + v) % 3 | |||
r.append('%d' % lastlvl) | |||
return ''.join(r) | |||
encoded = jm3coder('000' + encoded) | |||
print('jm3coded:', repr(encoded)) | |||
# make a "stretched" bit string | |||
stretched = ''.join(encoded[i:i + 50] + encoded[i:i + 50][-1] for i in range(0, len(encoded), 50)) | |||
print('stretched:', repr(stretched)) | |||
def jm3decoder(trits, lastlvl=0): | |||
'''Decodes a string encoded w/ jm3coder. | |||
lastlvl should/must be provided which is the last rx'd level | |||
(it must be 0, 1 or 2). | |||
''' | |||
lookup = { | |||
(0, 1): 0, | |||
(0, 2): 1, | |||
(1, 2): 0, | |||
(1, 0): 1, | |||
(2, 0): 0, | |||
(2, 1): 1, | |||
} | |||
r = [] | |||
for i in trits: | |||
lvl = int(i, 3) | |||
if lvl == lastlvl: | |||
continue | |||
r.append('%d' % lookup[(lastlvl, lvl)]) | |||
#r.append('%d' % ((lvl - lastlvl + 2) % 3)) | |||
lastlvl = lvl | |||
return ''.join(r) | |||
decoder = EncDec8B10B() | |||
stretched = jm3decoder(stretched) | |||
print(repr(stretched)) | |||
print(repr(decoder.decode(stretched))) | |||
print(repr(decoder.decode(''))) | |||
print('done') |
@@ -0,0 +1,167 @@ | |||
/*- | |||
* Copyright 2021 John-Mark Gurney. | |||
* | |||
* Redistribution and use in source and binary forms, with or without | |||
* modification, are permitted provided that the following conditions | |||
* are met: | |||
* 1. Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* 2. Redistributions in binary form must reproduce the above copyright | |||
* notice, this list of conditions and the following disclaimer in the | |||
* documentation and/or other materials provided with the distribution. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
* SUCH DAMAGE. | |||
* | |||
*/ | |||
#include <string.h> | |||
#include <misc.h> | |||
#include <sysinit.h> | |||
#include <main.h> | |||
static void | |||
c13led(void) | |||
{ | |||
GPIO_InitTypeDef GPIO_InitStruct; | |||
__HAL_RCC_GPIOA_CLK_ENABLE(); | |||
__HAL_RCC_GPIOB_CLK_ENABLE(); | |||
__HAL_RCC_GPIOC_CLK_ENABLE(); | |||
GPIO_InitStruct = (GPIO_InitTypeDef){ | |||
.Pin = GPIO_PIN_3, | |||
.Mode = GPIO_MODE_OUTPUT_PP, | |||
.Pull = GPIO_NOPULL, | |||
.Speed = GPIO_SPEED_FREQ_LOW, | |||
}; | |||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); | |||
GPIO_InitStruct = (GPIO_InitTypeDef){ | |||
.Pin = GPIO_PIN_13, | |||
.Mode = GPIO_MODE_OUTPUT_PP, | |||
.Pull = GPIO_NOPULL, | |||
.Speed = GPIO_SPEED_FREQ_LOW, | |||
}; | |||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); | |||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); | |||
} | |||
SYSINIT_VF(c13led, SI_SUB_HAL, SI_ORDER_SECOND, c13led); | |||
static TIM_HandleTypeDef htim2; | |||
/* 36.2.2 Step 1 */ | |||
void | |||
HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) | |||
{ | |||
} | |||
#define PERIOD_VALUE (700 - 1) | |||
void | |||
tim2ch4(void) | |||
{ | |||
GPIO_InitTypeDef GPIO_InitStruct; | |||
uint32_t uhPrescalerValue; | |||
/* | |||
* various parts from F1's | |||
* Projects/STM3210E_EVAL/Examples/TIM/TIM_PWMOutput/Src/main.c | |||
*/ | |||
uhPrescalerValue = (uint32_t)(SystemCoreClock / 2000000) - 1; | |||
/* 36.2.2 Step 2a */ | |||
__HAL_RCC_TIM2_CLK_ENABLE(); | |||
/* 36.2.2 Step 2b */ | |||
__HAL_RCC_GPIOA_CLK_ENABLE(); | |||
GPIO_InitStruct = (GPIO_InitTypeDef){ | |||
.Pin = GPIO_PIN_3, | |||
.Mode = GPIO_MODE_AF_PP, | |||
.Pull = GPIO_NOPULL, | |||
.Speed = GPIO_SPEED_FREQ_LOW, | |||
}; | |||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); | |||
/* 36.2.2 Step 4 */ | |||
htim2 = (TIM_HandleTypeDef){ | |||
.Instance = TIM2, | |||
/* TIM_Base_InitTypeDef */ | |||
.Init.Prescaler = uhPrescalerValue, | |||
.Init.Period = PERIOD_VALUE, | |||
.Init.CounterMode = TIM_COUNTERMODE_UP, | |||
.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE, | |||
}; | |||
HAL_TIM_PWM_Init(&htim2); | |||
} | |||
SYSINIT_VF(tim2ch4, SI_SUB_HAL, SI_ORDER_THIRD, tim2ch4); | |||
int | |||
main(void) | |||
{ | |||
debug_printf("starting...\n"); | |||
#if 0 | |||
/* toggle on LED */ | |||
for (;;) { | |||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); | |||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); | |||
HAL_Delay(250); | |||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); | |||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); | |||
HAL_Delay(250); | |||
} | |||
#else | |||
/* PA3 TIM2_CH4 */ | |||
TIM_OC_InitTypeDef oconfig; | |||
oconfig = (TIM_OC_InitTypeDef){ | |||
.OCMode = TIM_OCMODE_PWM1, | |||
.OCPolarity = TIM_OCPOLARITY_HIGH, | |||
.OCFastMode = TIM_OCFAST_DISABLE, | |||
.OCNPolarity = TIM_OCNPOLARITY_HIGH, | |||
.OCNIdleState = TIM_OCNIDLESTATE_RESET, | |||
.OCIdleState = TIM_OCIDLESTATE_RESET, | |||
.Pulse = PERIOD_VALUE, // OFF | |||
}; | |||
HAL_TIM_PWM_ConfigChannel(&htim2, &oconfig, TIM_CHANNEL_4); | |||
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4); | |||
for (int i = 0;; i = (i + 1) % 3) { | |||
switch (i) { | |||
case 0: | |||
TIM2->CCR4 = PERIOD_VALUE; | |||
break; | |||
case 1: | |||
TIM2->CCR4 = PERIOD_VALUE / 2; | |||
break; | |||
case 2: | |||
TIM2->CCR4 = 0; | |||
break; | |||
} | |||
#if 0 | |||
HAL_Delay(100); | |||
#else | |||
HAL_Delay(35); | |||
#endif | |||
} | |||
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4); | |||
#endif | |||
} |
@@ -0,0 +1 @@ | |||
-e ./encdec8b10b |
@@ -0,0 +1,17 @@ | |||
https://stackoverflow.com/questions/8877228/opencv-detect-blinking-lights | |||
ffmpeg -i PXL_20220806_231420638.mp4 -filter:v "crop=200:200:725:275" output.mp4 | |||
PXL_20220806_231420638.mp4 725x275 200x200 | |||
PXL_20220806_231644224.mp4 790x380 200x200 | |||
Mon Aug 8 17:24:55 PDT 2022 | |||
PXL_20220808_233318199.mp4 | |||
captures w/ a delay of 35ms instead of previous 34ms (for 4224.mp4) | |||
also w/ a smaller resistor, 68Ω instead of 100Ω. | |||
https://developer.android.com/reference/android/hardware/camera2/CaptureResult.html#SENSOR_EXPOSURE_TIME | |||
https://developer.android.com/reference/android/hardware/camera2/CaptureRequest#SENSOR_EXPOSURE_TIME |
@@ -0,0 +1,126 @@ | |||
import cv2 | |||
import numpy as np | |||
import sys | |||
winname = 'Diff' | |||
def tovalues(values, histo): | |||
return [ 0 if x < histo[1][1] else 2 if x > histo[1][2] else 1 for x in values ] | |||
def frameiter(fname): | |||
#vc = cv2.VideoCapture('output.mp4') | |||
#vc = cv2.VideoCapture('PXL_20220806_231420638.mp4') | |||
#vc = cv2.VideoCapture('PXL_20220806_231644224.mp4') | |||
#vc = cv2.VideoCapture('PXL_20220808_233318199.mp4') | |||
vc = cv2.VideoCapture('PXL_20220809_162724414.mp4') | |||
while True: | |||
r, frame = vc.read() | |||
if not r: | |||
break | |||
# base image processing | |||
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY, 1) | |||
yield frame | |||
def pixtot(frame): | |||
colsum = np.sum(frame, 0, np.float64) | |||
colsum = np.sum(colsum, 0, np.float64) | |||
return colsum | |||
def numpixels(frame): | |||
return pixtot(frame) / 255 | |||
sumhist = [] | |||
cont = False | |||
#cont = True | |||
key = 0 | |||
valuehist = [] | |||
basefr = None | |||
for frame in frameiter('output.mp4'): | |||
if basefr is None: | |||
basefr = frame | |||
continue | |||
frdiff = cv2.absdiff(basefr, frame) | |||
#hist = np.histogram(frdiff, bins=5) | |||
#print(repr(hist)) | |||
#frdiff = frame - basefr | |||
#frdiffbin = cv2.threshold(frdiff, 50, 100, cv2.THRESH_BINARY) | |||
frdiffbin = cv2.compare(frdiff, 50, cv2.CMP_GE) | |||
kernel = np.ones((4,4), np.uint8) | |||
frdiffbin = cv2.erode(frdiffbin, kernel, iterations = 2) | |||
numpix = numpixels(frdiffbin) | |||
print('np:', repr(numpix)) | |||
if numpix: | |||
# detected change | |||
# get average pixel value | |||
selected = cv2.bitwise_and(frame, frdiffbin) | |||
avg = pixtot(selected) / numpix | |||
print('avg:', avg) | |||
valuehist.append(avg) | |||
cv2.imshow('selected', selected) | |||
cv2.moveWindow('Base Frame', 1200, 300) | |||
if len(valuehist) > 6: | |||
print(repr(sorted(valuehist))) | |||
hist = np.histogram(valuehist, bins=3) | |||
print('hist:', repr(hist)) | |||
#print(repr(frdiffbin)) | |||
#moments = cv2.moments(frdiffbin) | |||
#((x, y), radius) = cv2.minEnclosingCircle(conts[0][0]) | |||
#x = int(x) | |||
#y = int(y) | |||
#radius = int(radius) | |||
#circ = ((x, y), radius) | |||
#white = (255,) | |||
#print(repr(moments)) | |||
#frdiff = cv2.circle(frdiff, circ[0], circ[1], white) | |||
cv2.imshow('Base Frame', basefr) | |||
cv2.moveWindow('Base Frame', 300, 300) | |||
cv2.imshow('Diff', frdiffbin) | |||
cv2.moveWindow('Diff', 600, 300) | |||
cv2.imshow('Next Frame', frame) | |||
cv2.moveWindow('Next Frame', 900, 300) | |||
# sum up the diffs | |||
colsum = np.sum(frdiff, 0, np.float64) | |||
colsum = np.sum(colsum, 0, np.float64) | |||
colsum = np.sum(colsum, 0, np.float64) | |||
sumhist.append(colsum) | |||
print(repr(colsum)) | |||
if not cont: | |||
key = cv2.waitKey(0) | |||
if key == ord('q'): | |||
break | |||
elif key == ord('c'): | |||
cont = True | |||
basefr = frame | |||
print(len(sumhist)) | |||
hist = np.histogram(sumhist, bins=5) | |||
print(repr(hist)) | |||
print(len(hist)) | |||
print(len(hist[1])) | |||
print(repr(valuehist)) | |||
hist = np.histogram(valuehist, bins=3) | |||
print(repr(hist)) | |||
print(repr(tovalues(valuehist, hist))) |
@@ -35,6 +35,10 @@ f103c8t6/stm32f1xx_hal_rcc_ex.c STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Src/stm | |||
f103c8t6/stm32f1xx_hal_rcc_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h | |||
f103c8t6/stm32f1xx_hal_rtc.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h | |||
f103c8t6/stm32f1xx_hal_rtc_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.h | |||
f103c8t6/stm32f1xx_hal_tim.c STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c | |||
f103c8t6/stm32f1xx_hal_tim_ex.c STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c | |||
f103c8t6/stm32f1xx_hal_tim.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h | |||
f103c8t6/stm32f1xx_hal_tim_ex.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h | |||
f103c8t6/stm32f1xx_hal_uart.c STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c | |||
f103c8t6/stm32f1xx_hal_uart.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h | |||
f103c8t6/stm32f1xx_ll_usb.h STM32CubeF1 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usb.h |
@@ -0,0 +1,262 @@ | |||
/** | |||
****************************************************************************** | |||
* @file stm32f1xx_hal_tim_ex.h | |||
* @author MCD Application Team | |||
* @brief Header file of TIM HAL Extended module. | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© Copyright (c) 2016 STMicroelectronics. | |||
* All rights reserved.</center></h2> | |||
* | |||
* This software component is licensed by ST under BSD 3-Clause license, | |||
* the "License"; You may not use this file except in compliance with the | |||
* License. You may obtain a copy of the License at: | |||
* opensource.org/licenses/BSD-3-Clause | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Define to prevent recursive inclusion -------------------------------------*/ | |||
#ifndef STM32F1xx_HAL_TIM_EX_H | |||
#define STM32F1xx_HAL_TIM_EX_H | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f1xx_hal_def.h" | |||
/** @addtogroup STM32F1xx_HAL_Driver | |||
* @{ | |||
*/ | |||
/** @addtogroup TIMEx | |||
* @{ | |||
*/ | |||
/* Exported types ------------------------------------------------------------*/ | |||
/** @defgroup TIMEx_Exported_Types TIM Extended Exported Types | |||
* @{ | |||
*/ | |||
/** | |||
* @brief TIM Hall sensor Configuration Structure definition | |||
*/ | |||
typedef struct | |||
{ | |||
uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. | |||
This parameter can be a value of @ref TIM_Input_Capture_Polarity */ | |||
uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. | |||
This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ | |||
uint32_t IC1Filter; /*!< Specifies the input capture filter. | |||
This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ | |||
uint32_t Commutation_Delay; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. | |||
This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ | |||
} TIM_HallSensor_InitTypeDef; | |||
/** | |||
* @} | |||
*/ | |||
/* End of exported types -----------------------------------------------------*/ | |||
/* Exported constants --------------------------------------------------------*/ | |||
/** @defgroup TIMEx_Exported_Constants TIM Extended Exported Constants | |||
* @{ | |||
*/ | |||
/** @defgroup TIMEx_Remap TIM Extended Remapping | |||
* @{ | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/* End of exported constants -------------------------------------------------*/ | |||
/* Exported macro ------------------------------------------------------------*/ | |||
/** @defgroup TIMEx_Exported_Macros TIM Extended Exported Macros | |||
* @{ | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/* End of exported macro -----------------------------------------------------*/ | |||
/* Private macro -------------------------------------------------------------*/ | |||
/** @defgroup TIMEx_Private_Macros TIM Extended Private Macros | |||
* @{ | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/* End of private macro ------------------------------------------------------*/ | |||
/* Exported functions --------------------------------------------------------*/ | |||
/** @addtogroup TIMEx_Exported_Functions TIM Extended Exported Functions | |||
* @{ | |||
*/ | |||
/** @addtogroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions | |||
* @brief Timer Hall Sensor functions | |||
* @{ | |||
*/ | |||
/* Timer Hall Sensor functions **********************************************/ | |||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef *sConfig); | |||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim); | |||
void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim); | |||
void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim); | |||
/* Blocking mode: Polling */ | |||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim); | |||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim); | |||
/* Non-Blocking mode: Interrupt */ | |||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim); | |||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim); | |||
/* Non-Blocking mode: DMA */ | |||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length); | |||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim); | |||
/** | |||
* @} | |||
*/ | |||
/** @addtogroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions | |||
* @brief Timer Complementary Output Compare functions | |||
* @{ | |||
*/ | |||
/* Timer Complementary Output Compare functions *****************************/ | |||
/* Blocking mode: Polling */ | |||
HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
/* Non-Blocking mode: Interrupt */ | |||
HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
/* Non-Blocking mode: DMA */ | |||
HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); | |||
HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
/** | |||
* @} | |||
*/ | |||
/** @addtogroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions | |||
* @brief Timer Complementary PWM functions | |||
* @{ | |||
*/ | |||
/* Timer Complementary PWM functions ****************************************/ | |||
/* Blocking mode: Polling */ | |||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
/* Non-Blocking mode: Interrupt */ | |||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
/* Non-Blocking mode: DMA */ | |||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); | |||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); | |||
/** | |||
* @} | |||
*/ | |||
/** @addtogroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions | |||
* @brief Timer Complementary One Pulse functions | |||
* @{ | |||
*/ | |||
/* Timer Complementary One Pulse functions **********************************/ | |||
/* Blocking mode: Polling */ | |||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel); | |||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel); | |||
/* Non-Blocking mode: Interrupt */ | |||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); | |||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); | |||
/** | |||
* @} | |||
*/ | |||
/** @addtogroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions | |||
* @brief Peripheral Control functions | |||
* @{ | |||
*/ | |||
/* Extended Control functions ************************************************/ | |||
HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, | |||
uint32_t CommutationSource); | |||
HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, | |||
uint32_t CommutationSource); | |||
HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, | |||
uint32_t CommutationSource); | |||
HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, | |||
TIM_MasterConfigTypeDef *sMasterConfig); | |||
HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, | |||
TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig); | |||
HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap); | |||
/** | |||
* @} | |||
*/ | |||
/** @addtogroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions | |||
* @brief Extended Callbacks functions | |||
* @{ | |||
*/ | |||
/* Extended Callback **********************************************************/ | |||
void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim); | |||
void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim); | |||
void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim); | |||
/** | |||
* @} | |||
*/ | |||
/** @addtogroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions | |||
* @brief Extended Peripheral State functions | |||
* @{ | |||
*/ | |||
/* Extended Peripheral State functions ***************************************/ | |||
HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim); | |||
HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(TIM_HandleTypeDef *htim, uint32_t ChannelN); | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/* End of exported functions -------------------------------------------------*/ | |||
/* Private functions----------------------------------------------------------*/ | |||
/** @addtogroup TIMEx_Private_Functions TIMEx Private Functions | |||
* @{ | |||
*/ | |||
void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma); | |||
void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma); | |||
/** | |||
* @} | |||
*/ | |||
/* End of private functions --------------------------------------------------*/ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /* STM32F1xx_HAL_TIM_EX_H */ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |