feat: STM32 Renode 시리얼 출력 수정 + 로그 정리
- uartBuf 버퍼 추가: SSE 연결 전 도착한 UART 데이터 재전송 (타이밍 이슈 해결) - Renode 로그 라인버퍼링 + ANSI 코드 제거 - 시리얼 모니터에 WARNING/INFO 숨김, Machine started + ERROR만 표시 - ILI9341 mock: &SPI1 → nullptr 패치 (cast-macro address-of 오류 수정) - STM32 보드 목록: 블루필/블랙필 한국어 표기 + Nucleo 3종 유지 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3083,8 +3083,8 @@ function _stm32PinResolve(s) {
|
||||
}
|
||||
|
||||
let _renodeGpioBuf = '';
|
||||
let _stm32LcdInited = false;
|
||||
function _stm32ParseGpio(raw) {
|
||||
// 텔레메트리: STX(0x02) "P:name:val" ETX(0x03) 패킷 추출, 나머지는 시리얼로
|
||||
_renodeGpioBuf += raw;
|
||||
let out = '';
|
||||
let i = 0;
|
||||
@@ -3093,17 +3093,45 @@ function _stm32ParseGpio(raw) {
|
||||
if (s < 0) { out += _renodeGpioBuf.slice(i); _renodeGpioBuf = ''; break; }
|
||||
out += _renodeGpioBuf.slice(i, s);
|
||||
const e = _renodeGpioBuf.indexOf('\x03', s + 1);
|
||||
if (e < 0) { _renodeGpioBuf = _renodeGpioBuf.slice(s); break; } // 패킷 미완성
|
||||
const pkt = _renodeGpioBuf.slice(s + 1, e); // "P:PA0:1"
|
||||
if (e < 0) { _renodeGpioBuf = _renodeGpioBuf.slice(s); break; }
|
||||
const pkt = _renodeGpioBuf.slice(s + 1, e);
|
||||
_renodeGpioBuf = _renodeGpioBuf.slice(e + 1);
|
||||
i = 0;
|
||||
const parts = pkt.split(':');
|
||||
if (parts[0] === 'P' && parts.length >= 3)
|
||||
_stm32UpdatePin(_stm32PinResolve(parts[1]), parts[2]);
|
||||
else if (parts[0] === 'L' && parts.length >= 3)
|
||||
_stm32LcdDraw(parts[1], parts.slice(2).join(':'));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function _stm32LcdDraw(op, data) {
|
||||
if (op === 'I') {
|
||||
const [w, h] = data.split(',').map(Number);
|
||||
_esp32TftW = w || 240; _esp32TftH = h || 320; _esp32TftCtx2d = null;
|
||||
_esp32TftDraw('I:' + _esp32TftW + ',' + _esp32TftH);
|
||||
_stm32LcdInited = true;
|
||||
return;
|
||||
}
|
||||
if (op === 'R') { _esp32TftDraw('R:' + parseInt(data)); return; }
|
||||
if (!_stm32LcdInited) {
|
||||
_stm32LcdInited = true;
|
||||
_esp32TftW = 240; _esp32TftH = 320; _esp32TftCtx2d = null;
|
||||
_esp32TftDraw('I:240,320');
|
||||
}
|
||||
const n = data.split(',').map(Number);
|
||||
switch (op) {
|
||||
case 'r': _esp32TftDraw('B:' + n.join(',')); break; // fillRect x,y,w,h,c
|
||||
case 'h': _esp32TftDraw('B:' + [n[0],n[1],n[2],1,n[3]].join(',')); break; // hline → fillRect h=1
|
||||
case 'v': _esp32TftDraw('B:' + [n[0],n[1],1,n[2],n[3]].join(',')); break; // vline → fillRect w=1
|
||||
case 'p': _esp32TftDraw('P:' + n.join(',')); break; // pixel x,y,c
|
||||
case 'l': _esp32TftDraw('L:' + n.join(',')); break; // line x0,y0,x1,y1,c
|
||||
case 'c': _esp32TftDraw('C:' + [n[0],n[1],n[2],n[4],n[3]].join(',')); break; // circle cx,cy,r,fill,c → C:cx,cy,r,c,fill
|
||||
case 't': _esp32TftDraw('T:' + n.join(',')); break; // char x,y,fg,bg,size,charcode
|
||||
}
|
||||
}
|
||||
|
||||
function _buildBluePillSVG(isF4) {
|
||||
const leftPins = [
|
||||
['GND','#666'],['GND','#666'],['3V3','#c0c090'],['NRST','#b0b090'],
|
||||
@@ -3170,6 +3198,12 @@ function _buildBluePillSVG(isF4) {
|
||||
function initSTM32RenodeMode(sessionId, fname, fqbn) {
|
||||
_renodeSessionId = sessionId;
|
||||
_renodeGpioBuf = '';
|
||||
_stm32LcdInited = false;
|
||||
_esp32TftCtx2d = null;
|
||||
const _tftSec = document.getElementById('tft-section');
|
||||
if (_tftSec) _tftSec.style.display = 'none';
|
||||
const _tftDot = document.getElementById('tft-dot');
|
||||
if (_tftDot) _tftDot.classList.remove('on');
|
||||
document.querySelector('.header h1').textContent = '🖥️ STM32 Emulator (Renode)';
|
||||
document.getElementById('filename').textContent = fname;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user