Skip to content

Commit

Permalink
Added ISR_NOBLOCK for timer ISRs when required to improve USB stabili…
Browse files Browse the repository at this point in the history
…ty. Added/improved a few Doxygen comments.
  • Loading branch information
N-Storm committed Jun 25, 2024
1 parent c465773 commit 0fc3410
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 7 deletions.
20 changes: 15 additions & 5 deletions firmware/lib/DLTransmitter/DLTransmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ DLTransmitter::DLTransmitter(uint8_t pin) : Livolo(pin)
* I.e. one code sequence are aired as "(remoteID << 7) + (keycode & 0x7F)".
* We always set remaining MSB in keycode to 1, it's used to find an end of sequence when we're shifting bits on transmit. */

/// @brief Sends button pressed packet, blocks until complete.
/// @param remoteID[in] Remote ID
/// @param keycode[in] Key code
/// @param use_timer[in] Set to true if you want to use hardware Timer for better accuracy. Will fallback to software method if timer will be unavailable.
/// @param idleCallback_ptr[in](optional) Pointer to a function(void) which will be called on idling. Should be really small to return very soon.
void DLTransmitter::sendButton(uint16_t remoteID, uint8_t keycode, bool use_timer, void (*idleCallback_ptr)(void)) {
// Use new Timer function if available & not used right now.
#ifdef DL_TIMER
Expand Down Expand Up @@ -184,8 +189,9 @@ void DLTransmitter::timer1_stop() {
sei();
}

/// @brief Changes time to next interrups by updating output compare registers
/// @brief Sets interrupt timings by updating output compare registers
/// @param ocr[in] OCR value (used values are defined in OCR_ macros)
/// @param ocr_aux[in](optional) OCR value for additional transition (for sending 0 in DL protocol)
inline void timer1_update(uint8_t ocr, uint8_t ocr_aux = 0) {
OCR1A = ocr;
OCR1C = ocr;
Expand All @@ -211,11 +217,9 @@ void inline switch_txPin() {
#endif
}

ISR(TIMER1_COMPA_vect) {
ISR(TIMER1_COMPA_vect, ISR_NOBLOCK) {
switch_txPin();

sei();

// TODO: no need to update OCR1A, OCR1C with a FULLBIT value
if ((dl_buf.bytes[0] & 0x01) == 0) {
timer1_update(OCR_FULLBIT, OCR_HALFBIT);
Expand All @@ -227,8 +231,14 @@ ISR(TIMER1_COMPA_vect) {
dl_buf.buf >>= 1;
}

/* Starting from GCC v8.x.x we have -mgas-isr-prologues which generates shorter ISR prologues.
* So the whole ISR below will be ~5 instructions - no need to add ISR_NOBLOCK. */
#if defined(__AVR__) && (__GNUC__ >= 8)
ISR(TIMER1_COMPB_vect) {
#else
ISR(TIMER1_COMPB_vect, ISR_NOBLOCK) {
#endif // __AVR__ && __GNUC__ >= 8
switch_txPin();
}

#endif // ifdef DL_TIMER
#endif // DL_TIMER
1 change: 0 additions & 1 deletion firmware/lib/DLUSB/DLUSB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ extern "C" {
{
// Type cast incoming data to dlusb_packet_t struct
dlusb_packet_t* p = (dlusb_packet_t*)data;
// TODO: Check why len are not <= sizeof(dlusb_packet_t)
if (p->report_id == REPORT_ID && (p->cmd_id == CMD_SWITCH || p->cmd_id == CMD_SWITCH_OLD) )
if (!store_packet(p, &rx_buffer))
return 0xff; // Return FAIL code
Expand Down
4 changes: 3 additions & 1 deletion firmware/src/DigiLivolo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ void mk_rdy_packet(dlusb_packet_t* packet) {
packet->btn_id = 0xEF;
}


/// @brief Wrapper for a member function DLUSB.refresh() to be called from a non-member class
void DLUSB_refresh_wrapper() {
DLUSB.refresh();
}
Expand Down Expand Up @@ -80,7 +82,7 @@ void loop() {
dltransmitter.sendButton(in_buf.remote_id, in_buf.btn_id);

DLUSB.refresh();

/* Send back same packet so that the host software can acknowledge it was
* processed by the device. */
DLUSB.write(&in_buf);
Expand Down

0 comments on commit 0fc3410

Please sign in to comment.