瀏覽代碼

Add cli() to protoect ADB critical timing part

led_matrix
tmk 10 年之前
父節點
當前提交
94823030f0
共有 1 個檔案被更改,包括 7 行新增11 行删除
  1. 7
    11
      protocol/adb.c

+ 7
- 11
protocol/adb.c 查看文件

#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "adb.h" #include "adb.h"
#include "debug.h"




// GCC doesn't inline functions normally // GCC doesn't inline functions normally
uint16_t adb_host_kbd_recv(void) uint16_t adb_host_kbd_recv(void)
{ {
uint16_t data = 0; uint16_t data = 0;
cli();
attention(); attention();
send_byte(0x2C); // Addr:Keyboard(0010), Cmd:Talk(11), Register0(00) send_byte(0x2C); // Addr:Keyboard(0010), Cmd:Talk(11), Register0(00)
place_bit0(); // Stopbit(0) place_bit0(); // Stopbit(0)
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
sei();
return 0; // No data to send return 0; // No data to send
} }
// ad hoc fix: without block inerrupt read wrong bit occasionally and get keys stuck
// TODO: is this needed anymore with improved timing?
//cli();
uint8_t n = 17; // start bit + 16 data bits uint8_t n = 17; // start bit + 16 data bits
do { do {
uint8_t lo = (uint8_t) wait_data_hi(130); uint8_t lo = (uint8_t) wait_data_hi(130);
data |= 1; data |= 1;
} }
else if (n == 17) { else if (n == 17) {
// Service Request
dprintf("Startbit ERROR\n");
sei(); sei();
return -2;
return -20;
} }
} }
while ( --n ); while ( --n );
// Stop bit can't be checked normally since it could have service request lenghtening // Stop bit can't be checked normally since it could have service request lenghtening
// and its high state never goes low. // and its high state never goes low.
if (!wait_data_hi(351) || wait_data_lo(91)) { if (!wait_data_hi(351) || wait_data_lo(91)) {
dprintf("Stopbit ERROR\n");
sei(); sei();
return -3;
return -21;
} }
sei(); sei();
return data; return data;


error: error:
dprintf("Bit ERROR\n");
sei(); sei();
return -4;
return -n;
} }


void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l)
{ {
cli();
attention(); attention();
send_byte(cmd); send_byte(cmd);
place_bit0(); // Stopbit(0) place_bit0(); // Stopbit(0)
send_byte(data_h); send_byte(data_h);
send_byte(data_l); send_byte(data_l);
place_bit0(); // Stopbit(0); place_bit0(); // Stopbit(0);
sei();
} }


// send state of LEDs // send state of LEDs