最近在研究 Loenrado 的USB,在\arduino-1.8.4\hardware\arduino\avr\cores\arduino\CDC.cpp 中发现有趣的代码:
// We check DTR state to determine if host port is open (bit 0 of lineState).
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
{
#if MAGIC_KEY_POS != (RAMEND-1)
// Backup ram value if its not a newer bootloader.
// This should avoid memory corruption at least a bit, not fully
if (magic_key_pos != (RAMEND-1)) {
*(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos;
}
#endif
// Store boot key
*(uint16_t *)magic_key_pos = MAGIC_KEY;
wdt_enable(WDTO_120MS);
}
这段代码是用来实现 Leonrado 刷新的:通过设置当前USB 传输速度为 1200,然后让板子重启进入Bootloader响应刷写指令而无需使用板载的 Reset按钮(未来会做更具体的分析)。
_usbLineInfo.dwDTERate 这里就是当前设定的USB 通讯速度,因此我们在这里添加代码根据当前速度设定LED On Off。加入的代码段如下:
#if MAGIC_KEY_POS != (RAMEND-1)
// For future boards save the key in the inproblematic RAMEND
// Which is reserved for the main() return value (which will never return)
if (_updatedLUFAbootloader) {
// horray, we got a new bootloader!
magic_key_pos = (RAMEND-1);
}
#endif
//LABZ_DEBUG_START
if (300 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
{
digitalWrite(2,HIGH);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
}
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
{
digitalWrite(2,LOW);
digitalWrite(3,HIGH);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
}
if (2400 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
{
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
}
if (4800 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
{
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,HIGH);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
}
if (9600 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
{
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,HIGH);
digitalWrite(7,LOW);
}
if (19200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
{
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,HIGH);
}
//LABZ_DEBUG_ENd
// We check DTR state to determine if host port is open (bit 0 of lineState).
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
{
#if MAGIC_KEY_POS != (RAMEND-1)
// Backup ram value if its not a newer bootloader.
// This should avoid memory corruption at least a bit, not fully
if (magic_key_pos != (RAMEND-1)) {
*(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos;
}
#endif
// Store boot key
*(uint16_t *)magic_key_pos = MAGIC_KEY;
wdt_enable(WDTO_120MS);
}
这样,当设定不同速度时, D2-D7 上的LED会分别亮起来。
编写一个简单的 Arduino代码
void setup() {
// put your setup code here, to run once:
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
}
void loop() {
// put your main code here, to run repeatedly:
}
比如当前的IDE 的 Serial Monitor 设定为 4800, D5上面的LED会亮
