Skip to content

Commit 708fcdb

Browse files
committed
[ISSUE-20]: post-merge refinement
1 parent 32481e7 commit 708fcdb

File tree

10 files changed

+65
-59
lines changed

10 files changed

+65
-59
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ THis list is supposed to grow longer and longer.
8989
* Device drivers
9090
* BME280 Temperature / Pressure / Humidity sensor
9191
* (_TODO_: cleanup) BH1750 Light sensor
92+
* WS2812B LED strip
9293
* etc (_TODO_)
9394
9495
### Simplifications

examples/1rmtmorse/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ ESP32.GPIO2 -- R1 --(A) D1 (K)-- ESP32.GND
6666
1. Play around with the memory size allocated to the RMT channel.
6767

6868
2. The ESP32 reference manual states that in `TX_CONTI_MODE`
69-
"there will be an idle level lasting one clk_div cycle between N and N+1 transmissions."
69+
"there will be an idle level lasting one `clk_div` cycle between N and N+1 transmissions."
7070
Solve this problem somehow.
7171

7272
3. Instead of periodic register scanning, use an ISR.
@@ -75,6 +75,6 @@ Solve this problem somehow.
7575
(transition start should be triggered by newline character).
7676

7777
5. Replace D1 with a speaker and make audio output.
78-
To achieve this you have to modulate the RMT pulses with a _carrier_ wave.
78+
To achieve this you have to modulate the RMT pulses with a *carrier* wave.
7979
The setup of the carrier is already implemented, you just have to switch on (set `CARRIER_EN` to `1`).
8080
What you still can do is playing around with the carrier frequency / duty cycle.

examples/1rmtmusic/rmtmusic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ static void _rmtmusic_init() {
265265

266266
// register ISR and enable it
267267
rmt_isr_init();
268-
rmt_isr_register(RMTMUSIC_CH, NULL, NULL, _rmtmusic_feed, NULL, &gsMusicState);
268+
rmt_isr_register(RMTMUSIC_CH, RMT_INT_TXTHRES, _rmtmusic_feed, &gsMusicState);
269269
rmt_isr_start(CPU_PRO, RMTINT_CH);
270270
}
271271

examples/1rmtws2812/rmtws2812.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ const Color gasStops[] = {
8888
static uint8_t gau8PreBuffer0[3 * STRIP_LENGTH];
8989
static uint8_t gau8PreBuffer1[3 * STRIP_LENGTH];
9090
static uint8_t gau8Buffer[3 * STRIP_LENGTH];
91-
static const SWs2812Iface gsWs2812Iface = {.eChannel = RMTWS2812_CH, .u8Blocks = RMTWS2812_MEM_BLOCKS};
92-
static SWs2812FeederState gsFeederState = {.sIface = gsWs2812Iface, .pu8Data = gau8Buffer, .szLen = sizeof (gau8Buffer), .szPos = 0};
91+
static SWs2812State gsFeederState;
92+
static bool gbFeederBusy = false;
9393

9494
// ==================== Implementation ================
9595
static void _fill_prebuffer(uint8_t *pu8Dest, uint8_t u8Stop0Idx, uint8_t u8Stop1Idx) {
@@ -128,8 +128,8 @@ static uint8_t *_rotbuf_weighted_avg(uint8_t *pu8Res, uint32_t u32Len, uint8_t *
128128
}
129129

130130
IRAM_ATTR static void _rmtws2812_txend_cb(void *pvParam) {
131-
SWs2812FeederState *psParam = (SWs2812FeederState*)pvParam;
132-
psParam->bBusy = false;
131+
bool *psParam = (bool*)pvParam;
132+
*psParam = false;
133133
}
134134

135135
static void _rmtws2812_init_data() {
@@ -140,7 +140,8 @@ static void _rmtws2812_init_data() {
140140
static void _rmtws2812_init_peripheral() {
141141
rmt_isr_init(); // ws2812_init will write into rmt_isr table
142142
rmt_init_controller(true, true);
143-
ws2812_init(RMTWS2812_GPIO, APB_FREQ_HZ, _rmtws2812_txend_cb, &gsFeederState);
143+
gsFeederState = ws2812_init_feederstate(gau8Buffer, sizeof (gau8Buffer), RMTWS2812_CH, RMTWS2812_MEM_BLOCKS);
144+
ws2812_init(RMTWS2812_GPIO, APB_FREQ_HZ, &gsFeederState, _rmtws2812_txend_cb, &gbFeederBusy);
144145

145146
// enable RMT ISR
146147
rmt_isr_start(CPU_PRO, RMTINT_CH);
@@ -151,6 +152,7 @@ static void _rmtws2812_cycle(uint64_t u64Ticks) {
151152
static bool bFirstRun = true;
152153

153154
if (bFirstRun) {
155+
gbFeederBusy = true;
154156
ws2812_start(&gsFeederState);
155157
bFirstRun = false;
156158
}
@@ -160,8 +162,8 @@ static void _rmtws2812_cycle(uint64_t u64Ticks) {
160162
gpsRMT->arInt[RMT_INT_CLR] = rmt_int_bit(RMTWS2812_CH, RMT_INT_TXEND);
161163
gsUART0.FIFO = 'E';
162164
}
163-
if (gsFeederState.szPos == gsFeederState.szLen && !gsFeederState.bBusy) {
164-
gsFeederState.szPos = 0;
165+
if (gsFeederState.szPos == gsFeederState.szLen && !gbFeederBusy) {
166+
gbFeederBusy = true;
165167
ws2812_start(&gsFeederState);
166168
}
167169
if (gpsRMT->arInt[RMT_INT_ST] & rmt_int_bit(RMTWS2812_CH, RMT_INT_ERR)) {

modules/bme280.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,16 @@ typedef union {
9292

9393
struct {
9494
bool bDirtyCtrlHum : 1;
95-
bool bDirtyStatus : 1; // meaning that the status bye must be read
96-
bool bDirtyCtrlMeas : 1; // note: async comm is not triggered until bModeSet is set.
95+
bool bDirtyStatus : 1; // meaning that the status bye must be read
96+
bool bDirtyCtrlMeas : 1; // note: async comm is not triggered until bModeSet is set.
9797
bool bDirtyConfig : 1;
9898
bool bDataUpdated : 1;
9999
bool bCalib0Ready : 1;
100100
bool bCalib1Ready : 1;
101101
bool bWaitingForRx : 1;
102-
bool bModeSet : 1; // triggers chain of state changes until the mode bits get written
102+
bool bModeSet : 1; // triggers chain of state changes until the mode bits get written
103103
bool bRequestForData : 1; // triggers chain of state changes until data bytes are read out
104-
bool bReset : 1; // triggers write to reset register
104+
bool bReset : 1; // triggers write to reset register
105105
uint32_t rsvd11 : 5;
106106
uint8_t u8CurAddr : 8;
107107
uint8_t u5CurLen : 5;
@@ -496,7 +496,7 @@ bool bme280_async_tx_cycle(const SI2cIfaceCfg *psIface, SBme280StateDesc *psStat
496496
} else if (!psFlags->bCalib1Ready) {
497497
_read_bytes(psIface, psEntry, psState, psState->au8Calib + MEMLEN_CALIB0, MEMADDR_CALIB1, MEMLEN_CALIB1);
498498
} else if (psFlags->bDirtyStatus) {
499-
_read_bytes(psIface, psEntry, psState, psState->au8Config + MEMADDR_STATUS - MEMADDR_CTRLH, MEMADDR_STATUS, 1);
499+
_read_bytes(psIface, psEntry, psState, psState->au8Config + (MEMADDR_STATUS - MEMADDR_CTRLH), MEMADDR_STATUS, 1);
500500
} else if (!psFlags->bDataUpdated) {
501501
_read_bytes(psIface, psEntry, psState, psState->au8Data, MEMADDR_DATA, MEMLEN_DATA);
502502
} else {

modules/bme280.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ extern "C" {
7373
uint32_t u32LastLabel;
7474
uint32_t u32CommState;
7575
// the following attributes are storing data trasmitted to / received from the target device
76-
uint8_t au8Calib[42]; ///< bytes at mem 0x88 .. 0xa1, 0xe1 .. 0xf0
77-
uint8_t au8Data[8]; ///< bytes at mem 0xf7 .. 0xfe
78-
uint8_t au8Config[4]; ///< bytes at mem 0xf2 .. 0xf5
76+
uint8_t au8Calib[42]; ///< bytes at mem 0x88 .. 0xa1, 0xe1 .. 0xf0
77+
uint8_t au8Data[8]; ///< bytes at mem 0xf7 .. 0xfe
78+
uint8_t au8Config[4]; ///< bytes at mem 0xf2 .. 0xf5
7979
} SBme280StateDesc;
8080

8181
// interface functions

modules/ws2812.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
#define RMT_CLK_NS (1000000 / RMT_FREQ_KHZ)
2222

2323
// ================ Local function declarations =================
24-
static void _rmt_config_channel(SWs2812Iface *psIface, uint8_t u8Divisor);
24+
static void _rmt_config_channel(const SWs2812Iface *psIface, uint8_t u8Divisor);
2525
void _byte_to_rmtram(RegAddr prDest, uint8_t u8Value);
26-
static bool _put_next_byte(SWs2812FeederState *psState);
26+
static bool _put_next_byte(SWs2812State *psState);
2727
static void _feeder(void *pvParam);
2828

2929
// =================== Global constants ================
@@ -46,7 +46,8 @@ const uint32_t *pu32EntryPair = (const uint32_t*)gau16Entries;
4646
// ==================== Local Data ================
4747

4848
// ==================== Implementation ================
49-
static void _rmt_config_channel(SWs2812Iface *psIface, uint8_t u8Divisor) {
49+
50+
static void _rmt_config_channel(const SWs2812Iface *psIface, uint8_t u8Divisor) {
5051
// rmt channel config
5152
SRmtChConf rChConf = {
5253
.r0 =
@@ -73,7 +74,7 @@ IRAM_ATTR void _byte_to_rmtram(RegAddr prDest, uint8_t u8Value) {
7374
}
7475
}
7576

76-
IRAM_ATTR static bool _put_next_byte(SWs2812FeederState *psState) {
77+
IRAM_ATTR static bool _put_next_byte(SWs2812State *psState) {
7778
uint32_t u32Offset = 8 * psState->szPos;
7879
RegAddr prDest = rmt_ram_addr(psState->sIface.eChannel, psState->sIface.u8Blocks, u32Offset);
7980
if (psState->szPos < psState->szLen) {
@@ -86,7 +87,7 @@ IRAM_ATTR static bool _put_next_byte(SWs2812FeederState *psState) {
8687
}
8788

8889
static void _feeder(void *pvParam) {
89-
SWs2812FeederState *psParam = (SWs2812FeederState*)pvParam;
90+
SWs2812State *psParam = (SWs2812State*)pvParam;
9091

9192
for (int i = 0; i < (psParam->sIface.u8Blocks * RMT_RAM_BLOCK_SIZE) / 16; ++i) {
9293
if (!_put_next_byte(psParam)) break;
@@ -95,16 +96,17 @@ static void _feeder(void *pvParam) {
9596

9697
// ============== Interface functions ==============
9798

98-
void ws2812_init(uint8_t u8Pin, uint32_t u32ApbClkFreq, Isr fTxEndCb, SWs2812FeederState *psFeederState) {
99+
void ws2812_init(uint8_t u8Pin, uint32_t u32ApbClkFreq, SWs2812State *psFeederState, Isr fTxEndCb, void *pvTxEndCbParam) {
99100
rmt_init_channel(psFeederState->sIface.eChannel, u8Pin, false);
100101
_rmt_config_channel(&psFeederState->sIface, u32ApbClkFreq / (1000 * RMT_FREQ_KHZ));
101-
rmt_isr_register(psFeederState->sIface.eChannel, fTxEndCb, NULL, _feeder, NULL, psFeederState);
102+
rmt_isr_register(psFeederState->sIface.eChannel, RMT_INT_TXTHRES, _feeder, psFeederState);
103+
rmt_isr_register(psFeederState->sIface.eChannel, RMT_INT_TXEND, fTxEndCb, pvTxEndCbParam);
102104
}
103105

104-
void ws2812_start(SWs2812FeederState *psFeederState) {
105-
_feeder(psFeederState);
106-
_feeder(psFeederState);
107-
psFeederState->bBusy = true;
108-
rmt_start_tx(psFeederState->sIface.eChannel, true);
106+
void ws2812_start(SWs2812State *psFeederState) {
107+
psFeederState->szPos = 0;
108+
_feeder(psFeederState);
109+
_feeder(psFeederState);
110+
rmt_start_tx(psFeederState->sIface.eChannel, true);
109111
}
110112

modules/ws2812.h

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,28 @@ extern "C" {
2121
} SWs2812Iface;
2222

2323
typedef struct {
24-
uint8_t *pu8Data;
25-
size_t szLen;
26-
size_t szPos;
27-
bool bBusy;
28-
SWs2812Iface sIface;
29-
} SWs2812FeederState;
30-
24+
uint8_t *pu8Data; ///< Points to data (GRB sequence) (Set by user)
25+
size_t szLen; ///< Length of the data (number of bytes)
26+
size_t szPos; ///< Current data cursor (Internal attribute)
27+
SWs2812Iface sIface; ///< Interface description
28+
} SWs2812State;
29+
30+
// ============= Inline functions ===============
31+
static inline SWs2812State ws2812_init_feederstate(uint8_t *pu8Data, size_t szLen, ERmtChannel eChannel, uint8_t u8Blocks) {
32+
SWs2812Iface sIface = {
33+
.eChannel = eChannel,
34+
.u8Blocks = u8Blocks
35+
};
36+
return (SWs2812State){
37+
.pu8Data = pu8Data,
38+
.szLen = szLen,
39+
.szPos = 0,
40+
.sIface = sIface};
41+
}
3142
// ============= Interface function declaration ===============
3243

33-
void ws2812_init(uint8_t u8Pin, uint32_t u32ApbClkFreq, Isr fTxEndCb, SWs2812FeederState *psFeederState);
34-
void ws2812_start(SWs2812FeederState *psFeederState);
44+
void ws2812_init(uint8_t u8Pin, uint32_t u32ApbClkFreq, SWs2812State *psFeederState, Isr fTxEndCb, void *pvTxEndCbParam);
45+
void ws2812_start(SWs2812State *psFeederState);
3546

3647
#ifdef __cplusplus
3748
}

src/rmt.c

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
typedef struct {
1818
Isr aafIsr[8][4];
19-
void *apvParam[8];
19+
void *apvParam[8][4];
2020
uint8_t abChannelEn;
2121
} SRmtIntDispatcher;
2222

@@ -37,7 +37,7 @@ IRAM_ATTR void _dispatch_isr(void *pvParam) {
3737
if (gpsRMT->arInt[RMT_INT_ST] & rmt_int_bit(iChannel, iInt)) {
3838
gpsRMT->arInt[RMT_INT_CLR] = rmt_int_bit(iChannel, iInt);
3939
if (NULL != psParam->aafIsr[iChannel][iInt]) {
40-
psParam->aafIsr[iChannel][iInt](psParam->apvParam[iChannel]);
40+
psParam->aafIsr[iChannel][iInt](psParam->apvParam[iChannel][iInt]);
4141
} else {
4242
// unhandled exception with registered RMT channel
4343
}
@@ -78,28 +78,18 @@ void rmt_isr_start(ECpu eCpu, uint8_t u8IntChannel) {
7878
/**
7979
* Registers ISRs to an RMT channel.
8080
* If a given interrupt type should not be handled, the corresponding Isr parameter should be NULL.
81-
* @param eChannel Identifies the RMT channel.
82-
* @param fTxEndIsr function to invoke in case of TXEND interrupt.
83-
* @param fRxEndIsr function to invoke in case of RXEND interrupt.
84-
* @param fTxThresholdIsr function to invoke in case of TXTHRESH interrupt.
85-
* @param fErrorIsr function to invoke in case of ERR interrupt.
81+
* @param eChannel Identifies the RMT channel
82+
* @param eIntType Interrupt type, either TXEND, RXEND, ERR or TXTHRES.
83+
* @param fIsr Function to invoke in case of eIntType interrupt.
8684
* @param pvParam parameter passed to the Isr functions.
8785
*/
88-
void rmt_isr_register(ERmtChannel eChannel, Isr fTxEndIsr, Isr fRxEndIsr, Isr fTxThresholdIsr, Isr fErrorIsr, void *pvParam) {
86+
void rmt_isr_register(ERmtChannel eChannel, ERmtIntType eIntType, Isr fIsr, void *pvParam) {
8987
gsIntDispatcher.abChannelEn |= (1 << eChannel);
9088

91-
gsIntDispatcher.aafIsr[eChannel][RMT_INT_TXEND] = fTxEndIsr;
92-
gsIntDispatcher.aafIsr[eChannel][RMT_INT_RXEND] = fRxEndIsr;
93-
gsIntDispatcher.aafIsr[eChannel][RMT_INT_TXTHRES] = fTxThresholdIsr;
94-
gsIntDispatcher.aafIsr[eChannel][RMT_INT_ERR] = fErrorIsr;
89+
gsIntDispatcher.aafIsr[eChannel][eIntType] = fIsr;
90+
gsIntDispatcher.apvParam[eChannel][eIntType] = pvParam;
9591

96-
gsIntDispatcher.apvParam[eChannel] = pvParam;
97-
98-
Reg rIntMask = 0;
99-
for (int iInt = 0; iInt < 4; ++iInt) {
100-
if (NULL != gsIntDispatcher.aafIsr[eChannel][iInt]) rIntMask |= rmt_int_bit(eChannel, iInt);
101-
}
102-
gpsRMT->arInt[RMT_INT_ENA] |= rIntMask;
92+
gpsRMT->arInt[RMT_INT_ENA] |= rmt_int_bit(eChannel, eIntType);
10393
}
10494

10595
/**

src/rmt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ extern "C" {
254254
void rmt_init_channel(ERmtChannel eChannel, uint8_t u8Pin, bool bInitLevel);
255255
void rmt_isr_init();
256256
void rmt_isr_start(ECpu eCpu, uint8_t u8IntChannel);
257-
void rmt_isr_register(ERmtChannel eChannel, Isr fTxEndIsr, Isr fRxEndIsr, Isr fTxThresholdIsr, Isr fErrorIsr, void *pvParam);
257+
void rmt_isr_register(ERmtChannel eChannel, ERmtIntType eIntType, Isr fIsr, void *pvParam);
258258

259259
#ifdef __cplusplus
260260
}

0 commit comments

Comments
 (0)