-
Notifications
You must be signed in to change notification settings - Fork 0
/
CD74HC4067.c
81 lines (72 loc) · 2.55 KB
/
CD74HC4067.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "CD74HC4067.h"
#define BIT_READ(value, bit) (((value) >> (bit)) & 0x01)
static const uint8_t MUX_TRUTH_TABLE[CD74HC4067_CHANNEL_COUNT] = {
0b00000000,
0b00001000,
0b00000100,
0b00001100,
0b00000010,
0b00001010,
0b00000110,
0b00001110,
0b00000001,
0b00001001,
0b00000101,
0b00001101,
0b00000011,
0b00001011,
0b00000111,
0b00001111
};
Multiplexer *initMultiplexer(GPIO_TypeDef *GPIOx, uint32_t dataS0, uint32_t dataS1, uint32_t dataS2, uint32_t dataS3, uint32_t enablePin, uint32_t signalPin) {
Multiplexer *mux = malloc(sizeof(struct Multiplexer));
if (mux == NULL) return NULL;
mux->GPIOx = GPIOx;
mux->dataS0 = dataS0;
mux->dataS1 = dataS1;
mux->dataS2 = dataS2;
mux->dataS3 = dataS3;
mux->enablePin = enablePin;
mux->signalPin = signalPin;
mux->selectedChannel = -1;
if (signalPin != 0) {
LL_GPIO_ResetOutputPin(GPIOx, signalPin);
}
LL_GPIO_SetOutputPin(GPIOx, enablePin); // High level means disable input/output signal
LL_GPIO_ResetOutputPin(GPIOx, dataS0 | dataS1 | dataS2 | dataS3); // set all data pins low, by default channel 0 selected
return mux;
}
void setEnableMultiplexer(Multiplexer *mux, bool isEnabled) {
if (mux != NULL) {
if (isEnabled) {
LL_GPIO_ResetOutputPin(mux->GPIOx, mux->enablePin);
} else {
LL_GPIO_SetOutputPin(mux->GPIOx, mux->enablePin);
}
}
}
void writeMultiplexer(Multiplexer *mux, MultiplexerChannel channel, MultiplexerValue value) {
if (mux != NULL && mux->signalPin != 0) {
setMultiplexerChannel(mux, channel);
if (value == MUX_HIGH) {
LL_GPIO_SetOutputPin(mux->GPIOx, mux->signalPin);
} else {
LL_GPIO_ResetOutputPin(mux->GPIOx, mux->signalPin);
}
}
}
void setMultiplexerChannel(Multiplexer *mux, MultiplexerChannel channel) {
if (mux != NULL && mux->selectedChannel != channel) {
uint32_t pinMask = 0;
uint8_t muxValue = MUX_TRUTH_TABLE[channel];
pinMask |= (BIT_READ(muxValue, 3) ? mux->dataS0 : mux->dataS0 << 16);
pinMask |= (BIT_READ(muxValue, 2) ? mux->dataS1 : mux->dataS1 << 16);
pinMask |= (BIT_READ(muxValue, 1) ? mux->dataS2 : mux->dataS2 << 16);
pinMask |= (BIT_READ(muxValue, 0) ? mux->dataS3 : mux->dataS3 << 16);
LL_GPIO_SetOutputPin(mux->GPIOx, pinMask);
mux->selectedChannel = channel;
}
}
void deleteMultiplexer(Multiplexer *mux) {
free(mux);
}