51 #error "LEDComm Driver requires CH_USE_QUEUES"
54 #if LEDCOMM_USE_LCOM1 || defined(__DOXYGEN__)
57 #if LEDCOMM_USE_LCOM2 || defined(__DOXYGEN__)
61 #define LED_SYNC_COUNT 18
80 static size_t write(
void *ip,
const uint8_t *bp,
size_t n) {
86 static size_t read(
void *ip, uint8_t *bp,
size_t n) {
92 static msg_t put(
void *ip, uint8_t b) {
94 return chOQPutTimeout(&((
LEDCommDriver_t *)ip)->oqueue, b, TIME_INFINITE);
97 static msg_t
get(
void *ip) {
102 static msg_t putt(
void *ip, uint8_t b, systime_t timeout) {
107 static msg_t gett(
void *ip, systime_t timeout) {
112 static size_t writet(
void *ip,
const uint8_t *bp,
size_t n, systime_t time) {
114 return chOQWriteTimeout(&((
LEDCommDriver_t *)ip)->oqueue, bp, n, time);
117 static size_t readt(
void *ip, uint8_t *bp,
size_t n, systime_t time) {
123 write, read, put,
get,
124 putt, gett, writet, readt
128 return ledCommPollLinkStatus(l);
132 return !ledCommPollLinkStatus(l);
145 chIQResetI(&(l->iqueue));
146 chOQResetI(&(l->oqueue));
147 chnAddFlagsI(l, CHN_CONNECTED);
151 chSysUnlockFromIsr();
164 chnAddFlagsI(l, CHN_DISCONNECTED);
168 chSysUnlockFromIsr();
178 .cathode_port = GPIOB, .cathode_pad = 4,
179 .cathode_extmode = (EXT_CH_MODE_FALLING_EDGE | EXT_MODE_GPIOB),
180 .data_bits = LEDCOMM_DEFAULT_DATA_BITS,
186 if (ldp->enable == 0) {
192 if (ldp->count == 1) {
194 extChannelDisableI(&EXTD_LEDComm, ldp->cathode_pad);
195 palSetPadMode(ldp->cathode_port, ldp->cathode_pad, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_LOWEST);
197 }
else if (ldp->count == 2) {
198 if (ldp->txrdy == 1) {
211 chSysUnlockFromIsr();
219 ldp->tx_char = (uint8_t)b;
225 }
else if (ldp->count == 3) {
227 if (isLinkDown(ldp) || ldp->txrdy == 1) {
230 }
else if (ldp->tx_bits == 0) {
233 if (ldp->tx_char & (1 << (ldp->tx_bits - 1))) {
238 ldp->tx_bits = ldp->tx_bits - 1;
240 }
else if (ldp->count >= 4 && ldp->count <= 13) {
241 if ((ldp->count == 5 && ldp->txbit == SPACE) ||
242 (ldp->count == 9 && ldp->txbit == MARK) ||
243 (ldp->count == 13 && ldp->txbit == STOP)) {
246 if (ldp->txbit == STOP) {
252 }
else if (ldp->count >= 14 && ldp->count < 46) {
258 if (ldp->count != 0) {
298 #if LEDCOMM_USE_LCOM1
302 #if LEDCOMM_USE_LCOM2
325 chEvtInit(&ldp->event);
342 #if !LEDCOMM_THREADED
343 extern GPTConfig GPTC_LEDComm;
345 extern EXTConfig extcfg;
346 extern WORKING_AREA(waLEDCommThread, LEDCOMM_THREAD_STACK_SIZE);
348 chDbgCheck(ldp != NULL,
"ldStart");
355 if (config == NULL) {
356 config = &default_config;
370 extcfg.channels[ldp->cathode_pad].cb = (extcallback_t)extcb1;
382 ldp->rx_register = 0;
389 chThdCreateStatic(waLEDCommThread,
sizeof(waLEDCommThread), HIGHPRIO, LEDCommThread, NULL);
393 extStart(&EXTD_LEDComm, &extcfg);
395 gptObjectInit(&GPTD_LEDComm);
396 gptStart(&GPTD_LEDComm, &GPTC_LEDComm);
397 gptStartContinuous(&GPTD_LEDComm, 2);
415 chDbgCheck(ldp != NULL,
"ldStop");
422 chOQResetI(&ldp->oqueue);
423 chIQResetI(&ldp->iqueue);
426 extStop(&EXTD_LEDComm);
448 chDbgCheck(ldp != NULL,
"ldIncomingDataI");
451 if (chIQIsEmptyI(&ldp->iqueue))
452 chnAddFlagsI(ldp, CHN_INPUT_AVAILABLE);
455 if (chIQPutI(&ldp->iqueue, b) < Q_OK)
478 chDbgCheck(ldp != NULL,
"ldRequestDataI");
480 b = chOQGetI(&ldp->oqueue);
483 chnAddFlagsI(ldp, CHN_OUTPUT_EMPTY);
void ldStart(LEDCommDriver_t *ldp, const LEDCommConfig_t *config)
Configures and starts the driver.
ioportid_t cathode_port
The port where the LED cathode is connected.
ioportid_t anode_port
The port where the LED anode is connected.
#define LD_OVERRUN_ERROR
Overflow happened.
uint16_t threshold
The highest number of elapsed HAL ticks that represents a 'shine' – try LEDCOMM_DEFAULT_THRESHOLD (3...
uint32_t cathode_extmode
The processor-specific EXT mode used to configure the extcfg table.
void ldStop(LEDCommDriver_t *ldp)
Stops the driver.
uint8_t data_bits
LEDCOMM_DATA_BITS8 or LEDCOMM_DATA_BITS7
LEDCommDriver virtual methods table.
LEDComm Driver macros and structures.
void ldInit(void)
LEDComm Driver initialization.
LEDComm Driver configuration structure.
msg_t ldRequestDataI(LEDCommDriver_t *ldp)
Handles outgoing data.
#define LEDCOMM_BUFFERS_SIZE
The size of the input and output queues.
void ldObjectInit(LEDCommDriver_t *ldp, qnotify_t inotify, qnotify_t onotify)
Initializes a generic full duplex driver object.
void ldIncomingDataI(LEDCommDriver_t *ldp, uint8_t b)
Handles incoming data.
#define LEDCOMM_DEFAULT_SYNCS
Number of MARKs before considering the link is "up".
const struct LEDCommDriverVMT * vmt
Virtual Methods Table.
Full duplex LEDComm driver class.
#define LEDCOMM_DATA_BITS7
7 data bits per character (default).
ioportmask_t cathode_pad
The pad where the LED cathode is connected.
ioportmask_t anode_pad
The pad where the LED anode is connected.