Skip to content

optimize/v1 #1

@AlecsHome

Description

@AlecsHome

Заменяем «громадный if/else» на switch + inline (–60 байт)
Файл: main.c
Замените ваш громадный блок if/else if (data[1] == ...) на компактный switch:

/* внутри usbFunctionSetup() /
uint8_t retVal = 0;
switch (data[1]) {
case USBASP_FUNC_CONNECT: retVal = usbConnect(data); break;
case USBASP_FUNC_DISCONNECT: retVal = usbDisconnect(); break;
case USBASP_FUNC_I2C_INIT: retVal = usbI2Cinit(); break;
case USBASP_FUNC_I2C_START: i2c_start(); break;
case USBASP_FUNC_I2C_STOP: i2c_stop(); break;
case USBASP_FUNC_I2C_ACK: retVal = usbI2CAck(data); break;
case USBASP_FUNC_I2C_WRITEBYTE: retVal = usbI2CWriteByte(data); break;
case USBASP_FUNC_I2C_READBYTE: retVal = usbI2CReadByte(data); break;
case USBASP_FUNC_I2C_READ: retVal = usbI2CRead(data); break;
case USBASP_FUNC_I2C_WRITE: retVal = usbI2CWrite(data); break;
/
добавьте остальные case по аналогии */
default: retVal = 0xFF; break;
}
replyBuffer[0] = retVal;
len = (retVal == 0xFF) ? 1 : 0;
return len;

Добавляем inline-функции внизу main.c
/* ---------- inline-ветви для switch ---------- */
static uint8_t usbConnect(uint8_t data) {
/
выбор скорости по jumper PC2 */
prog_sck = (PINC & (1 << PC2)) ? USBASP_ISP_SCK_AUTO : USBASP_ISP_SCK_8;

ispConnect();
uint8_t sig[3];
ispReadSignature(sig);          // читаем сигнатуру
uint32_t signature = ((uint32_t)sig[0]<<16)|((uint32_t)sig[1]<<8)|sig[2];

/* автоматически ставим ≤ 750 кГц для 1284/2560 */
if (signature == 0x1E9705 || signature == 0x1E9801 || signature == 0x1E9802)
    prog_sck = USBASP_ISP_SCK_375;

prog_address_newmode = 0;
return ispEnterProgrammingMode();

}

static uint8_t usbI2CWrite(uint8_t data) {
/
компактный page-write (64 байт за 5 мс) – см. ниже */
return i2cPageWrite(data);
}

Page-write I²C — в 30-60 раз быстрее
Добавьте внизу main.c:

/* ---------- I²C – EEPROM page-write (≤ 64 байт за 5 мс) ---------- */
static uint8_t i2cPageWrite(uint8_t *data) {
uint8_t chunk = (i2c_eeprom_mode) ? 64 - (prog_address & 0x3F) : 255;
if (chunk > len) chunk = len;

/* заголовок (один раз) */
if (!prog_address_sent) {
    i2c_start();
    uint8_t dev = i2c_eeprom_device_addr | ((prog_address >> 15) & 0x0E);
    if (i2c_send_byte(dev | I2C_WRITE) != I2C_ACK) goto nak;
    if (i2c_eeprom_addr_size >= 1) if (i2c_send_byte(prog_address >> 8) != I2C_ACK) goto nak;
    if (i2c_eeprom_addr_size >= 2) if (i2c_send_byte(prog_address & 0xFF) != I2C_ACK) goto nak;
    prog_address_sent = 1;
}

/* пишем */
for (uint8_t i = 0; i < chunk; i++) {
    if (i2c_send_byte(data[i]) != I2C_ACK) goto nak;
    prog_address++;
}
prog_nbytes -= chunk;

/* конец страницы / потока */
if (prog_nbytes == 0 || (prog_address & 0x3F) == 0) {
    i2c_stop(); _delay_ms(5);       // TWR
    prog_address_sent = 0;
}

if (prog_nbytes == 0) {
    prog_state = PROG_STATE_IDLE;
    i2c_eeprom_mode = 0;
    return 1;
}
return chunk;                       // сколько приняли

nak:
i2c_stop(); prog_state = PROG_STATE_IDLE; prog_address_sent = 0; i2c_eeprom_mode = 0;
return 0xFE;
}

Прототипы — добавьте вверх main.c
/* прототипы новых inline-функций */
static uint8_t usbConnect(uint8_t *data);
static uint8_t usbI2CWrite(uint8_t *data);
static uint8_t i2cPageWrite(uint8_t *data);

case USBASP_FUNC_READFLASH: retVal = usbReadFlash(); break;
case USBASP_FUNC_WRITEFLASH: retVal = usbWriteFlash(data); break;
case USBASP_FUNC_READEEPROM: retVal = usbReadEEPROM(); break;
case USBASP_FUNC_WRITEEEPROM: retVal = usbWriteEEPROM(data);

/* ---------- Flash – page-write (≥ 128 КБ поддерживается) ---------- */
static uint8_t usbWriteFlash(uint8_t *data) {
uint32_t page_base = prog_pagesize ? (prog_address & ~(prog_pagesize - 1)) : 0;
uint8_t poll = !prog_pagesize;

for (uint8_t i = 0; i < len; i++) {
    if (ispWriteFlash(prog_address, data[i], poll)) { retVal = 0xFB; goto exit; }
    if (prog_pagesize && (--prog_pagecounter == 0)) {
        if (ispFlushPage(page_base)) { retVal = 0xFA; goto exit; }
        page_base += prog_pagesize;
        prog_pagecounter = prog_pagesize;
    }
    prog_address++;
}
prog_nbytes -= len;
if (prog_nbytes == 0) {
    if (prog_pagesize && prog_pagecounter != prog_pagesize) {
        if (ispFlushPage((prog_address - 1) & ~(prog_pagesize - 1))) { retVal = 0xFA; goto exit; }
    }
    prog_state = PROG_STATE_IDLE;
    return 1;
}
return 0;

}

/* ---------- EEPROM – page-write (≤ 64 КБ) ---------- */
static uint8_t usbWriteEEPROM(uint8_t *data) {
if (prog_address >= 0x10000UL) return 0xFC; // защита 64 КБ
uint8_t chunk = (i2c_eeprom_mode) ? 64 - (prog_address & 0x3F) : 255;
if (chunk > len) chunk = len;

if (!prog_address_sent) {                     // START + device + адрес
    i2c_start();
    uint8_t dev = i2c_eeprom_device_addr | ((prog_address >> 15) & 0x0E);
    if (i2c_send_byte(dev | I2C_WRITE) != I2C_ACK) goto nak;
    if (i2c_eeprom_addr_size >= 1) if (i2c_send_byte(prog_address >> 8) != I2C_ACK) goto nak;
    if (i2c_eeprom_addr_size >= 2) if (i2c_send_byte(prog_address & 0xFF) != I2C_ACK) goto nak;
    prog_address_sent = 1;
}
for (uint8_t i = 0; i < chunk; i++) {
    if (i2c_send_byte(data[i]) != I2C_ACK) goto nak;
    prog_address++;
}
prog_nbytes -= chunk;
if (prog_nbytes == 0 || (prog_address & 0x3F) == 0) {
    i2c_stop(); _delay_ms(5);       // TWR
    prog_address_sent = 0;
}
if (prog_nbytes == 0) { prog_state = PROG_STATE_IDLE; return 1; }
return chunk;                       // сколько приняли

nak:
i2c_stop(); prog_state = PROG_STATE_IDLE; prog_address_sent = 0; return 0xFE;
}

/* прототипы новых функций */
static uint8_t usbReadFlash(void);
static uint8_t usbWriteFlash(uint8_t *data);
static uint8_t usbReadEEPROM(void);
static uint8_t usbWriteEEPROM(uint8_t *data);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions