/*
* stm32.c - implementing STM32F10x-ISP functions
* part of STM32ISP
* copyright (c) 2012 Kai (ba5ag.kai@gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include "serial.h"
#include "stm32.h"
#include "memmap.h"
#include "gpio.h"
#include "config.h"
#define STM32_ACK 0x79
#define STM32_NACK 0x1F
/**
* maxim length of block for read/write
*/
#define MAXLEN 256
#define MAXTRY 4
#define TM_BOOTP 2000 // delay after change bootp
#define TM_RESET 200000 // delay after RESET down
typedef struct
{
int serial_fd;
// int error;
uint8_t version;
uint8_t cmd[16];
uint8_t pid[8];
// int flash;
// int ram;
int readprotect;
int writeprotect;
}Stm32Info;
static Stm32Info board;
static int sendCommand(unsigned char byte);
static int waitAck();
static unsigned char *addrPacket(unsigned int addr, unsigned char *buffer);
static unsigned char calcChecksum(unsigned char* data, unsigned int len);
static int stm32WriteBlock(unsigned char *data, unsigned int len, unsigned int addr);
/**
* Init serial port and sync with the board
* @param port the serial port, for example: /dev/ttyS0 or COM1
* @param baudrate the bardrate used during the burning
* @return STM_OK if the port is inited and the board is connected;
* STM_ERR if the port can not be opened, or the board can not be connected
*/
int stm32Init(const char* port, unsigned int baudrate)
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
int ret = STM_ERR;
ret = serialOpen(port, baudrate, 8, 'E', 1);
if ( ret>0 ) {
board.serial_fd = ret;
printf("Serial port %s open.\n", port);
ret = stm32Reboot2isp();
if ( ret == STM_ERR ) {
serialClose(board.serial_fd);
}
} else {
printf("Serial port %s open failed.\n", port);
exit(-1);
}
return ret;
}
/**
* close serial port
*/
void stm32Close()
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
serialClose(board.serial_fd);
}
int stm32Reboot2isp()
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
int ret = STM_ERR;
int i;
for ( i=0; ret == STM_ERR && i< MAXTRY; i++ ) {
gpio_out(BOOTPIN,1); //boot0 拉高 stm32 system boot
usleep(TM_BOOTP);
printf("Reboot board to isp.\n");
stm32Reboot();
ret = stm32Sync();
// printf("ret=%d\n",ret);
}
return ret;
}
void stm32Reboot(void)
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
printf("stm32 reset\n");
gpio_out(RESETPIN,0); //stm32 reboot
usleep(TM_RESET);
gpio_set_value(RESETPIN,1);
usleep(TM_RESET);
}
int stm32Sync()
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
int ret = STM_ERR;
static unsigned char STM32_INIT = 0x7F;
unsigned char r;
int rr;
int i;
// printf("Sync");
fflush(stdout);
for ( i=0; i<MAXTRY; i++ ) {
printf(".");
fflush(stdout);
rr = serialWrite(board.serial_fd, &STM32_INIT, 1);
if ( rr == SER_OK ) {
serialFlush(board.serial_fd);
rr = serialRead(board.serial_fd, &r, sizeof(r));
if ( rr == SER_OK ) {
if ( r==STM32_ACK || r==STM32_NACK) {
ret = STM_OK;
break;
}
}
}
}
printf("\n");
if ( ret == STM_OK ) {
printf("Connected to board.\n");
} else {
printf("Can not connect to board, ");
if ( rr == SER_ERR ) {
printf(" failed.\n");
} else {
printf(" timed-out.\n");
}
}
return ret;
}
int stm32CmdGet()
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
int ret = STM_ERR;
if ( sendCommand(0x00)==STM_OK ) {
#if DEBUG
int i;
#endif
unsigned char num;
serialRead(board.serial_fd, &num, 1); // number of bytes
serialRead(board.serial_fd, &board.version, 1);
serialRead(board.serial_fd, board.cmd, num);
if ( waitAck()==STM_OK ) {
#if DEBUG
printf("Bootloader version: %x.%x\nCommand set-[", board.version >> 4, board.version & 0x0F);
for ( i=0; i < num; i++ )
printf(" %02X", board.cmd[i]);
printf("]\n");
#endif
ret = STM_OK;
}
}
if ( ret == STM_ERR ) {
printf("STM32-Get: command error!\n");
}
return ret;
}
int stm32GetVersion()
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
int ret = STM_ERR;
if ( sendCommand(0x01) == STM_OK ) {
unsigned char buf[3];
serialRead(board.serial_fd, buf, 3);
printf("Bootloader version: %x.%x\n", buf[0] >> 4, buf[0] & 0x0F);
printf("%02X-%02X\n", buf[1], buf[2]);
if ( waitAck() == STM_OK ) {
ret = STM_OK;
}
}
if ( ret == STM_ERR ) {
printf("STM32-GetVersion: command error!\n");
}
return ret;
}
int stm32GetID()
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
int ret = STM_ERR;
if (sendCommand(0x02) == STM_OK ) {
unsigned char num;
int i;
serialRead(board.serial_fd, &num, 1);
serialRead(board.serial_fd, board.pid, num+1);
printf("Product ID=");
for ( i=0; i<num+1; i++ ) {
printf("%02X", board.pid[i]);
}
printf("\n");
if ( waitAck() == STM_OK ) {
ret = STM_OK;
}
}
if ( ret == STM_ERR ) {
printf("Command-getID: command error!\n");
}
return ret;
}
/**
* Read from the chip.
* It read data from anywhere in the chip: falsh or ram. The max length can be read is 256-byte.
*/
int stm32Read(unsigned char *data, unsigned int len, unsigned int addr)
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
int ret = STM_ERR;
unsigned char addr_buffer[5];
// printf("STM32-Read: %08X(%d)\n", addr, len);
if ( sendCommand(0x11) == STM_OK ) {
serialWrite(board.serial_fd, addrPacket(addr, addr_buffer), 5);
if ( waitAck() == STM_OK ) {
if ( sendCommand(len - 1) == STM_OK ) {
if ( serialRead(board.serial_fd, data, len) == STM_OK) {
ret = STM_OK;
} else {
printf("STM32-Read: data error!\n");
}
} else {
printf("STM32-Read: length error!\n");
}
} else {
printf("STM32-Read: address error!\n");
}
} else {
printf("STM32-Read: command error!\n");
}
return ret;
}
int stm32Verify(MemMap* mm)
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
int ret = STM_ERR;
MemBlock* pBlock;
printf("STM-32 Verifying\n");
for ( pBlock = mm->head; pBlock; pBlock = pBlock->next ) {
unsigned int address = pBlock->address;
unsigned int loc = 0;
unsigned char buf[MAXLEN];
printf("%08X:", address);
fflush(stdout);
while ( address+loc < pBlock->lastValid ) {
int size = pBlock->lastValid - (address + loc);
// printf("address=%08X, loc=%d\n", address, loc);
if ( size > MAXLEN)
size = MAXLEN;
if ( stm32Read(buf, size, address+loc) == STM_OK ) {
int i;
for ( i=0; i<size; i++ ) {
if ( pBlock->data[loc] != buf[i] ) {
printf("\nSTM32-Verify: not match at %08X:data=%02X,chip=%02X.\n", address+loc, pBlock->data[loc], buf[i]);
goto EXIT;
}
loc++;
}
printf(".");
fflush(stdout);
} else {
printf("\nSTM32-Verify: can not read!\n");
goto EXIT;
}
}
printf("Done.\n");
}
printf("STM32 Verity success.\n");
EXIT:
return ret;
}
int stm32Erase()
{
#if DEBUG
printf(""__FILE__" %s:\n",__func__);
#endif
int ret = STM_ERR;
unsigned char buffer[] = {0xFF, 0xFF, 0x00};
#if DEBUG
printf("\nSTM32-Erase: %X\n", board.cmd[6]);
#endif
if ( board.cmd[6] == 0x43 ) {
if ( sendCommand(0x43) == STM_OK ) {
if ( sendCommand(0xFF) ==
评论0
最新资源