Skip to content

Commit 8ef07a5

Browse files
committed
[ISSUE-24]: TM1637 driver and example
1 parent 323e0bb commit 8ef07a5

File tree

12 files changed

+609
-9
lines changed

12 files changed

+609
-9
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,14 @@ THis list is supposed to grow longer and longer.
8383
* Low level peripheral access (via registers).
8484
* Peripheral controller drivers
8585
* I2C
86-
* RMT (TODO: example on RX)
86+
* RMT
8787
* _TODO_ SPI
8888
* _TODO_ etc.
8989
* Device drivers
9090
* BME280 Temperature / Pressure / Humidity sensor
9191
* (_TODO_: cleanup) BH1750 Light sensor
92+
* DHT22 Temperature / Humidity sensor
93+
* TM1637 4x7 segment display
9294
* WS2812B LED strip
9395
* etc (_TODO_)
9496
@@ -119,6 +121,6 @@ Feel free to fork this project and play around with it integrating your own sens
119121
120122
## About license
121123
122-
The memory arrangement (see esp32.ld) and start-up code (main.c) is based on [esp32-minimal](https://github.com/aykevl/esp32-minimal).
123-
This project also contains code (see xtutils.h) directly taken from the official [ESP32 SDK](https://github.com/espressif/esp-idf),
124+
The memory arrangement (see [esp32.ld](ld/esp32.ld)) and start-up code ([main.c](src/main.c)) is based on [esp32-minimal](https://github.com/aykevl/esp32-minimal).
125+
This project also contains code (see [xtutils.h](src/xtutils.h)) directly taken from the official [ESP32 SDK](https://github.com/espressif/esp-idf),
124126
which is released under Apache-2.0.

configure.ac

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ AC_CONFIG_SUBDIRS([examples/1rmtblink])
2222
AC_CONFIG_SUBDIRS([examples/1rmtdht])
2323
AC_CONFIG_SUBDIRS([examples/1rmtmorse])
2424
AC_CONFIG_SUBDIRS([examples/1rmtmusic])
25+
AC_CONFIG_SUBDIRS([examples/1rmttm1637])
2526
AC_CONFIG_SUBDIRS([examples/1rmtws2812])
2627
AC_CONFIG_SUBDIRS([examples/3prog1])
2728
AC_CONFIG_SUBDIRS([ld])
@@ -39,6 +40,7 @@ AC_CONFIG_FILES([
3940
examples/1rmtdht/Makefile
4041
examples/1rmtmorse/Makefile
4142
examples/1rmtmusic/Makefile
43+
examples/1rmttm1637/Makefile
4244
examples/1rmtws2812/Makefile
4345
examples/3prog1/Makefile
4446
ld/Makefile

examples/1rmtdht/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ The 1-wire protocol is implemented in `modules/dht22.c`.
1212
#### Connections
1313

1414
```
15-
ESP32.GPIO2 -- S1.OUT
16-
ESP32.GND -- S1.-
17-
ESP32.VCC -- S1.+
15+
ESP32.GPIO21 -- S1.OUT
16+
ESP32.GND -- S1.-
17+
ESP32.VCC -- S1.+
1818
```
1919

2020
#### Practices

examples/1rmttm1637/Makefile.am

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
include $(top_srcdir)/scripts/elf2bin.mk
2+
include $(top_srcdir)/ld/flags.mk
3+
4+
noinst_HEADERS = defines.h
5+
6+
AM_CFLAGS = -std=c11 -flto
7+
8+
if WITH_BINARIES
9+
AM_LDFLAGS += \
10+
-T $(top_srcdir)/ld/esp32.rom.ld \
11+
-T $(top_srcdir)/ld/esp32.rom.libgcc.ld \
12+
-T $(top_srcdir)/ld/esp32.rom.newlib-data.ld \
13+
-T $(top_srcdir)/ld/esp32.rom.newlib-locale.ld \
14+
-T $(top_srcdir)/ld/esp32.rom.newlib-nano.ld \
15+
-T $(top_srcdir)/ld/esp32.rom.newlib-time.ld \
16+
-T $(top_srcdir)/ld/esp32.rom.redefined.ld \
17+
-T $(top_srcdir)/ld/esp32.rom.syscalls.ld
18+
else
19+
AM_LDFLAGS += \
20+
-T $(top_srcdir)/ld/esp32.rom.ld \
21+
-T $(top_srcdir)/ld/esp32.rom.libgcc.ld \
22+
-T $(top_srcdir)/ld/esp32.rom.redefined.ld \
23+
-T $(top_srcdir)/ld/esp32.rom.syscalls.ld
24+
endif
25+
26+
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/modules
27+
LDADD = $(top_builddir)/src/libesp32basic.a $(top_builddir)/modules/libesp32modules.a
28+
29+
bin_PROGRAMS = \
30+
rmttm1637.elf
31+
32+
if WITH_BINARIES
33+
CLEANFILES = \
34+
rmttm1637.bin
35+
endif
36+
37+
BUILT_SOURCES = $(CLEANFILES)

examples/1rmttm1637/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
### TM1637 display example
2+
3+
In this example the TM1637 displays hexadecimal numbers form `0` to `F`.
4+
Each digit displays the same number.
5+
The colon between the 2nd and the 3rd digits is blinking every second.
6+
Each number is displayed for 3 seconds:
7+
1 second full brightness, 1 second medium brightness and 1 second low brightness.
8+
9+
10+
#### Hardware components
11+
12+
* X1: TM1637 display
13+
14+
#### Connections
15+
16+
```
17+
ESP32.GPIO21 -- X1.CLK
18+
ESP32.GPIO19 -- X1.DIO
19+
ESP32.GND -- X1.GND
20+
ESP32.VCC -- X1.VCC
21+
```
22+
23+
#### Practices
24+

examples/1rmttm1637/defines.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2024 SZIGETI János
3+
*
4+
* This file is part of Bilis ESP32 Basic, which is released under GNU General Public License.version 3.
5+
* See LICENSE or <https://www.gnu.org/licenses/> for full license details.
6+
*/
7+
#ifndef DEFINES_H
8+
#define DEFINES_H
9+
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
// TIMINGS
15+
// const -- do not change this value
16+
#define APB_FREQ_HZ 80000000U // 80 MHz
17+
18+
// variables
19+
#define TIM0_0_DIVISOR 2U
20+
#define START_APP_CPU 0U
21+
#define SCHEDULE_FREQ_HZ 1000U // 1KHz
22+
23+
// derived invariants
24+
#define CLK_FREQ_HZ (APB_FREQ_HZ / TIM0_0_DIVISOR) // 40 MHz
25+
#define TICKS_PER_MS (CLK_FREQ_HZ / 1000U) // 40000
26+
#define TICKS_PER_US (CLK_FREQ_HZ / 1000000U) // 40
27+
#define NS_PER_TICKS (1000000000 / CLK_FREQ_HZ)
28+
29+
#define TICKS2NS(X) ((X) * NS_PER_TICKS)
30+
#define TICKS2US(X) ((X) / TICKS_PER_US)
31+
#define MS2TICKS(X) ((X) * TICKS_PER_MS)
32+
#define HZ2APBTICKS(X) (APB_FREQ_HZ / (X))
33+
34+
#ifdef __cplusplus
35+
}
36+
#endif
37+
38+
#endif /* DEFINES_H */
39+

examples/1rmttm1637/rmttm1637.c

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright 2024 SZIGETI János
3+
*
4+
* This file is part of Bilis ESP32 Basic, which is released under GNU General Public License.version 3.
5+
* See LICENSE or <https://www.gnu.org/licenses/> for full license details.
6+
*/
7+
#include <stdbool.h>
8+
#include <inttypes.h>
9+
#include <stdio.h>
10+
#include <string.h>
11+
#include <ctype.h>
12+
13+
#include "tm1637.h"
14+
#include "gpio.h"
15+
#include "main.h"
16+
#include "rmt.h"
17+
#include "defines.h"
18+
#include "romfunctions.h"
19+
#include "iomux.h"
20+
#include "dport.h"
21+
#include "timg.h"
22+
#include "typeaux.h"
23+
#include "utils/uartutils.h"
24+
25+
// =================== Hard constants =================
26+
// #1: Timings
27+
#define RMTTM1637_PERIOD_MS 500U
28+
29+
// #2: Channels / wires / addresses
30+
#define CLK_GPIO 21U
31+
#define DIO_GPIO 19U
32+
#define CLK_CH RMT_CH1
33+
#define DIO_CH RMT_CH0
34+
35+
#define RMTINT_CH 23U
36+
37+
// ============= Local types ===============
38+
39+
// ================ Local function declarations =================
40+
static void _rmttm1637_ready(void *pvParam);
41+
static void _rmttm1637_init();
42+
static void _rmttm1637_cycle(uint64_t u64Ticks);
43+
44+
// =================== Global constants ================
45+
const bool gbStartAppCpu = START_APP_CPU;
46+
const uint16_t gu16Tim00Divisor = TIM0_0_DIVISOR;
47+
const uint64_t gu64tckSchedulePeriod = (CLK_FREQ_HZ / SCHEDULE_FREQ_HZ);
48+
49+
// ==================== Local Data ================
50+
const uint8_t gau8NumToSeg[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
51+
static STm1637State gsTm1637State;
52+
static const TimerId gsTimer = {.eTimg = TIMG_0, .eTimer = TIMER0};
53+
static uint64_t gu64TckStart;
54+
// ==================== Implementation ================
55+
56+
static void _rmttm1637_ready(void *pvParam) {
57+
STm1637State *psParam = (STm1637State*) pvParam;
58+
uint64_t u64TckStop = timg_ticks(gsTimer);
59+
uart_printf(&gsUART0, "Hello (%08X) %d ns\n", psParam->u32Internals, TICKS2NS((uint32_t) (u64TckStop - gu64TckStart)));
60+
}
61+
62+
static void _rmttm1637_init() {
63+
rmt_isr_init();
64+
rmt_init_controller(true, true);
65+
STm1637Iface sIface = { CLK_GPIO, DIO_GPIO, CLK_CH, DIO_CH};
66+
gsTm1637State = tm1637_config(&sIface);
67+
tm1637_init(&gsTm1637State, APB_FREQ_HZ);
68+
tm1637_set_readycb(&gsTm1637State, _rmttm1637_ready, &gsTm1637State);
69+
gpio_pin_enable(2);
70+
gpio_pin_out_on(2);
71+
rmt_isr_start(CPU_PRO, RMTINT_CH);
72+
}
73+
74+
static void _rmttm1637_cycle(uint64_t u64Ticks) {
75+
static uint64_t u64NextTick = MS2TICKS(RMTTM1637_PERIOD_MS);
76+
static uint8_t au8Data[4];
77+
static uint8_t u8DatIdx = 0; // What number to display (put into au8Data)? Cycling through gau8NumToSeg: [0..15]
78+
static uint8_t u8Phase = 0; // Display phase: last bit is 0: display dot (8th segment of the digits), bits 1, 2: brightness level
79+
80+
if (u64NextTick <= u64Ticks) {
81+
// local, derived variables
82+
bool bDot = (0 == (u8Phase & 1));
83+
uint8_t u8Brightness = 7 - (3 * (u8Phase / 2)); // three levels: 7, 4, 1
84+
85+
uart_printf(&gsUART0, "Cycle %u %u\t", u8DatIdx, u8Phase);
86+
tm1637_set_brightness(&gsTm1637State, true, u8Brightness);
87+
for (int i = 0; i < 4; ++i) {
88+
au8Data[i] = gau8NumToSeg[u8DatIdx] | (bDot ? 0x80 : 0x00);
89+
}
90+
tm1637_set_data(&gsTm1637State, au8Data);
91+
gu64TckStart = timg_ticks(gsTimer);
92+
tm1637_display(&gsTm1637State);
93+
94+
// jump to next state
95+
++u8Phase;
96+
if (6 == u8Phase) {
97+
u8Phase = 0;
98+
++u8DatIdx;
99+
if (u8DatIdx == ARRAY_SIZE(gau8NumToSeg)) {
100+
u8DatIdx = 0;
101+
}
102+
}
103+
u64NextTick += MS2TICKS(RMTTM1637_PERIOD_MS);
104+
}
105+
}
106+
107+
// ====================== Interface functions =========================
108+
109+
void prog_init_pro_pre() {
110+
gsUART0.CLKDIV = APB_FREQ_HZ / 115200;
111+
112+
_rmttm1637_init();
113+
}
114+
115+
void prog_init_app() {
116+
}
117+
118+
void prog_init_pro_post() {
119+
}
120+
121+
void prog_cycle_app(uint64_t u64tckNow) {
122+
}
123+
124+
void prog_cycle_pro(uint64_t u64tckNow) {
125+
_rmttm1637_cycle(u64tckNow);
126+
}

examples/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
AUTOMAKE_OPTIONS =
2-
SUBDIRS=0blink 0button 0hello 0ledctrl 1rmtblink 1rmtdht 1rmtmorse 1rmtmusic 3prog1 1rmtws2812
2+
SUBDIRS=0blink 0button 0hello 0ledctrl 1rmtblink 1rmtdht 1rmtmorse 1rmtmusic 1rmttm1637 3prog1 1rmtws2812

modules/Makefile.am

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ libesp32modules_a_AR=$(AR) rcs
55

66
lib_LIBRARIES = libesp32modules.a
77

8-
include_HEADERS = bh1750.h bme280.h dht22.h ws2812.h
8+
include_HEADERS = bh1750.h bme280.h dht22.h tm1637.h ws2812.h
99
nodist_include_HEADERS =
1010

11-
libesp32modules_a_SOURCES = bh1750.c bme280.c dht22.c ws2812.c
11+
libesp32modules_a_SOURCES = bh1750.c bme280.c dht22.c tm1637.c ws2812.c
1212
nodist_libesp32modules_a_SOURCES =
1313

1414
CLEANFILES =

0 commit comments

Comments
 (0)