Compare commits

...

22 Commits

Author SHA1 Message Date
  John-Mark Gurney 9d2ab93cfb Merge branch 'main' into blinkled 2 months ago
  John-Mark Gurney 6736f1eb6e add links on how to change camera settings on android.. 2 months ago
  John-Mark Gurney d923278740 support generating a private/public key pair by running this... 2 months ago
  John-Mark Gurney 4656f790ff add test for pk version of the commands... 2 months ago
  John-Mark Gurney f3c328d707 add tests for python version round trip... and minor fix for seeding 2 months ago
  John-Mark Gurney d2baf9a0e7 fix misspelling of by 2 months ago
  John-Mark Gurney 301920977b clean up test output, and verify that the error message is correct.. 2 months ago
  John-Mark Gurney 5a4e45f39e fix running with shared keys... 2 months ago
  John-Mark Gurney 415e650c69 make printing ctype arrays pretty. 2 months ago
  John-Mark Gurney a4f76dc0bb add code to do tristate led blinking... 6 months ago
  John-Mark Gurney 82c49b3ca0 a bit of work to try to detect blinking leds... 6 months ago
  John-Mark Gurney 5c0a22a790 now that main has merged in, sysinit_run is a constructor.. 6 months ago
  John-Mark Gurney c1233d75bf Merge branch 'main' into blinkled 6 months ago
  John-Mark Gurney 9eff782ffe simple code that blinks the led.. 6 months ago
  John-Mark Gurney cc450a3488 add algorithm version of the lookup table. 6 months ago
  John-Mark Gurney 7aeaed651f add code that does binary to three level + clock recovery... 6 months ago
  John-Mark Gurney 455c410b89 rename so name is consistent... 6 months ago
  John-Mark Gurney e7e742150d add a working framework for doing 8b10b encoding/decoding.. 9 months ago
  John-Mark Gurney 88b5957bf5 comment which pins for programming to save me looking at the pdf.. 9 months ago
  John-Mark Gurney 900b0f2ae5 use family independent main.h to support l1.. 9 months ago
  John-Mark Gurney 39b1c229dc Merge commit 'ae0f979e1aa9ee734bd6b4b8d74bea8e7e112142' as 'blinkled/encdec8b10b' 9 months ago
  John-Mark Gurney ae0f979e1a Squashed 'blinkled/encdec8b10b/' content from commit 28ed9d5 9 months ago
25 changed files with 15292 additions and 0 deletions
Split View
  1. +55
    -0
      blinkled/Makefile
  2. +24
    -0
      blinkled/README.md
  3. +6
    -0
      blinkled/encdec8b10b/.gitignore
  4. +9
    -0
      blinkled/encdec8b10b/.travis.yml
  5. +21
    -0
      blinkled/encdec8b10b/LICENSE
  6. +26
    -0
      blinkled/encdec8b10b/Makefile
  7. +88
    -0
      blinkled/encdec8b10b/README.md
  8. +1
    -0
      blinkled/encdec8b10b/encdec8b10b/__init__.py
  9. +2219
    -0
      blinkled/encdec8b10b/encdec8b10b/core.py
  10. +16
    -0
      blinkled/encdec8b10b/requirements.txt
  11. +17
    -0
      blinkled/encdec8b10b/setup.py
  12. +0
    -0
      blinkled/encdec8b10b/tests/__init__.py
  13. +7
    -0
      blinkled/encdec8b10b/tests/context.py
  14. +110
    -0
      blinkled/encdec8b10b/tests/test_class.py
  15. +87
    -0
      blinkled/encdec8b10b/tests/test_suite.py
  16. +82
    -0
      blinkled/genseq.py
  17. +167
    -0
      blinkled/main.c
  18. +1
    -0
      blinkled/requirements.txt
  19. +17
    -0
      blinkled/sampledata/info.txt
  20. +126
    -0
      blinkled/sampledata/t.py
  21. +4
    -0
      stm32/.srcs
  22. +7483
    -0
      stm32/f103c8t6/stm32f1xx_hal_tim.c
  23. +2129
    -0
      stm32/f103c8t6/stm32f1xx_hal_tim.h
  24. +2335
    -0
      stm32/f103c8t6/stm32f1xx_hal_tim_ex.c
  25. +262
    -0
      stm32/f103c8t6/stm32f1xx_hal_tim_ex.h

+ 55
- 0
blinkled/Makefile View File

@@ -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>

+ 24
- 0
blinkled/README.md View File

@@ -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)

+ 6
- 0
blinkled/encdec8b10b/.gitignore View File

@@ -0,0 +1,6 @@
.idea
__pycache__
build/
venv/
dist/
*egg-info*

+ 9
- 0
blinkled/encdec8b10b/.travis.yml View File

@@ -0,0 +1,9 @@
language: python
python:
- "3.4"
- "3.5"
- "3.6"
install:
- pip install -e .
script:
- make test

+ 21
- 0
blinkled/encdec8b10b/LICENSE View File

@@ -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.

+ 26
- 0
blinkled/encdec8b10b/Makefile View File

@@ -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/*

+ 88
- 0
blinkled/encdec8b10b/README.md View File

@@ -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

+ 1
- 0
blinkled/encdec8b10b/encdec8b10b/__init__.py View File

@@ -0,0 +1 @@
from .core import EncDec8B10B as EncDec8B10B

+ 2219
- 0
blinkled/encdec8b10b/encdec8b10b/core.py
File diff suppressed because it is too large
View File


+ 16
- 0
blinkled/encdec8b10b/requirements.txt View File

@@ -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

+ 17
- 0
blinkled/encdec8b10b/setup.py View File

@@ -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
blinkled/encdec8b10b/tests/__init__.py View File


+ 7
- 0
blinkled/encdec8b10b/tests/context.py View File

@@ -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

+ 110
- 0
blinkled/encdec8b10b/tests/test_class.py View File

@@ -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')

+ 87
- 0
blinkled/encdec8b10b/tests/test_suite.py View File

@@ -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()

+ 82
- 0
blinkled/genseq.py View File

@@ -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')

+ 167
- 0
blinkled/main.c View File

@@ -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
}

+ 1
- 0
blinkled/requirements.txt View File

@@ -0,0 +1 @@
-e ./encdec8b10b

+ 17
- 0
blinkled/sampledata/info.txt View File

@@ -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

+ 126
- 0
blinkled/sampledata/t.py View File

@@ -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)))

+ 4
- 0
stm32/.srcs View File

@@ -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

+ 7483
- 0
stm32/f103c8t6/stm32f1xx_hal_tim.c
File diff suppressed because it is too large
View File


+ 2129
- 0
stm32/f103c8t6/stm32f1xx_hal_tim.h
File diff suppressed because it is too large
View File


+ 2335
- 0
stm32/f103c8t6/stm32f1xx_hal_tim_ex.c
File diff suppressed because it is too large
View File


+ 262
- 0
stm32/f103c8t6/stm32f1xx_hal_tim_ex.h View File

@@ -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>&copy; 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****/

Loading…
Cancel
Save