int stlink2_swim_write_range(programmer_t *pgm, stm8_device_t *device, unsigned char *buffer, unsigned int start, unsigned int length, const memtype_t memtype) { stlink2_init_session(pgm); stlink2_write_byte(pgm, 0x00, device->regs.CLK_CKDIVR); if(memtype == FLASH || memtype == EEPROM || memtype == OPT) { stlink2_write_and_read_byte(pgm, 0x00, device->regs.FLASH_IAPSR); } if(memtype == FLASH) { stlink2_write_byte(pgm, 0x56, device->regs.FLASH_PUKR); stlink2_write_byte(pgm, 0xae, device->regs.FLASH_PUKR); } if(memtype == EEPROM || memtype == OPT) { stlink2_write_byte(pgm, 0xae, device->regs.FLASH_DUKR); stlink2_write_byte(pgm, 0x56, device->regs.FLASH_DUKR); } if(memtype == FLASH || memtype == EEPROM || memtype == OPT) { stlink2_write_and_read_byte(pgm, 0x56, device->regs.FLASH_IAPSR); // mov 0x56, FLASH_IAPSR } int i; int BLOCK_SIZE = device->flash_block_size; for(i = 0; i < length; i+=BLOCK_SIZE) { if(memtype == FLASH || memtype == EEPROM || memtype == OPT) { // stlink2_write_word(pgm, 0x01fe, device->regs.FLASH_CR2); // mov 0x01fe, FLASH_CR2 stlink2_write_byte(pgm, 0x01, device->regs.FLASH_CR2); // mov 0x01fe, FLASH_CR2; 0x817e - enable write OPT bytes if(device->regs.FLASH_NCR2 != 0) { // Device have FLASH_NCR2 register stlink2_write_byte(pgm, 0xFE, device->regs.FLASH_NCR2); } } // The first 8 packet bytes are getting transmitted // with the same USB bulk transfer as the command itself msg_init(cmd_buf, 0xf40a); format_int(&(cmd_buf[2]), BLOCK_SIZE, 2, MP_BIG_ENDIAN); format_int(&(cmd_buf[6]), start + i, 2, MP_BIG_ENDIAN); memcpy(&(cmd_buf[8]), &(buffer[i]), 8); msg_send(pgm, cmd_buf, sizeof(cmd_buf)); // Transmitting the rest msg_send(pgm, &(buffer[i + 8]), BLOCK_SIZE - 8); // Waiting for the transfer to process TRY(128, HI(stlink2_get_status(pgm)) == BLOCK_SIZE); if(memtype == FLASH || memtype == EEPROM || memtype == OPT) { stlink2_wait_until_transfer_completes(pgm, device); } } if(memtype == FLASH || memtype == EEPROM || memtype == OPT) { stlink2_write_and_read_byte(pgm, 0x56, device->regs.FLASH_IAPSR); // mov 0x56, FLASH_IAPSR } stlink2_write_byte(pgm, 0x00, 0x7f80); stlink2_write_byte(pgm, 0xb6, 0x7f80); stlink2_finish_session(pgm); return(length); }
void stlink2_init_session(programmer_t *pgm) { int i; char f4_cmd_arg1[] = { 0x07, 0x07, 0x08, 0x07, 0x04, 0x03, 0x05, }; for(i = 0; i < sizeof(f4_cmd_arg1); i++) { stlink2_cmd(pgm, 0xf400 | f4_cmd_arg1[i], 0); TRY(8, stlink2_get_status(pgm) == 0); } stlink2_write_byte(pgm, 0xa0, 0x7f80); // mov 0x0a, SWIM_CSR2 ;; Init SWIM stlink2_cmd(pgm, 0xf408, 0); TRY(8, stlink2_get_status(pgm) == 0); stlink2_write_and_read_byte(pgm, 0xa0, 0x7f99); stlink2_cmd(pgm, 0xf40c, 0); msg_recv_int8(pgm); // 0x08 (or 0x0a if used stlink2_write_byte() instead) }
void stlink2_wait_until_transfer_completes(programmer_t *pgm, stm8_device_t *device) { TRY(8, stlink2_write_and_read_byte(pgm, 0x82, device->regs.FLASH_IAPSR) & 0x4); }