Нет... я рано радовался. Какие-то места пишутся криво.
Пытаясь разобраться я упростил задачу - не читаю HEX файл, а генерирую данные сам, точнее пишу только нули. ОДнако нули пишутся только в первые 128 байт.
Вот мой код в C++ Builder:
Код
ADDRESS=0x00;
for (ic = 0; ic < 10; ic++)
{
ADDRESS_HB=(unsigned char)(ADDRESS>>8); // Получаем старший байт
ADDRESS_LB=(unsigned char)ADDRESS; // Получаем младший байт
CRC=0;
CommandTrans(ADDRESS_HB); //Передаем старший байт
recieved_byte=Recieved(); // получаем от контроллера сообщение, какой байт он принял
RichEdit1->Lines->Add(AnsiString(recieved_byte)); // выводим, на практике все правильно
CommandTrans(ADDRESS_LB); //Передаем младший байт
recieved_byte=Recieved(); // получаем от контроллера сообщение, какой байт он принял
RichEdit1->Lines->Add(AnsiString(recieved_byte)); // выводим, на практике все правильно
//Выводим номер страницы, 16-ти битный Адрес и его байты (чтобы быть уверенным, что они правильно разложились)
RichEdit1->Lines->Add("Пишем страницу №"+AnsiString(page)+" Адрес:"+AnsiString(ADDRESS)+" ("+AnsiString(ADDRESS_HB)+":"+AnsiString(ADDRESS_LB)+")");
for (jc =0; jc < 128; jc++)
{
CommandTrans(0x00); //Для простоты заполняем страницу нулями
}
CommandTrans(0x00); //Отправляем CRC. Bootloader проверяет только сумму байт - естественно CRC равен нулю
//Принимаем отчет от контроллера, который проверяет контрольную сумму принятых данных и проверяет
// все ли правильно записалось во флеш
recieved_byte=Recieved();
if (recieved_byte==-2) RichEdit1->Lines->Add("Нет ответа от контроллера");
else RichEdit1->Lines->Add(AnsiString((const char)recieved_byte));
if (recieved_byte=='$') RichEdit1->Lines->Add("Ошибка FLASH");
if (recieved_byte=='!')
{
RichEdit1->Lines->Add("Следующая страница");
page_ok=1;
}
if (recieved_byte=='@')
{
RichEdit1->Lines->Add("Ошибка CRC");
}
Application->ProcessMessages();
page++;
//Увеличиваем адрес на 128 байт - адрес новой страницы.
ADDRESS+=0x80;
}
А вот код бутлодера:
Код
char GetPage(void)
{
char LocalCheckSum = 0;
char CheckSum = 0;
// The programming software generates a simple checksum in the
// same fashion as below to check for data transmission errors
for (j=0;j<PageByte;j++)
{
PageBuffer[j]=getchar();
LocalCheckSum += PageBuffer[j];
}
CheckSum = getchar();
//putchar(LocalCheckSum);
if (LocalCheckSum == CheckSum) return 1;
else return 0;
}
void BootLoad(void)
{
unsigned char crc,bbb;
// Send chip data to the programming software so that it knows
// how to format transmissions
putchar(DeviceID);
putchar(FlashSize);
putchar(BootSize);
putchar(PageSize);
// "!" means all ok and send the next data if there is more
putchar('!');
while(1)
{
bbb=getchar();
PageAddress = (unsigned int)bbb << 8; // Receive PageAddress high byte
putchar(bbb);
bbb=getchar();
PageAddress += bbb; // Add PageAddress low byte
putchar(bbb);
if (PageAddress == 0xffff) ExecCode(); // The windows program sends this value when finished
//#if defined _CHIP_ATMEGA128_
//if (PageAddress >> 8) RAMPZ = 1;
//else RAMPZ=0;
//#endif
PageAddress = PageAddress << AddressLshift; //essentially the same as multiply by PageSize
if (GetPage()) //receive one page of data followed by a checksum byte and verify data
{
for (i=0;i<PageByte;i+=2) //fill temporary buffer in 2 byte chunks from PageBuffer
{
Pagedata=PageBuffer[i]+(PageBuffer[i+1]<<8);
while (SPMCR&1); //wait for spm complete
CurrentAddress=PageAddress+i;
spmcrval=1;
#asm
movw r30, r6 ;//move CurrentAddress to Z pointer
mov r1, r3 ;//move Pagedata MSB reg 1
mov r0, r2 ;//move Pagedata LSB reg 1
sts SpmcrAddr, r10 ;//move spmcrval to SPM control register
spm ;//store program memory
#endasm
}
while (SPMCR&1); //wait for spm complete
spmcrval=3; //erase page
#asm
movw r30, r4 ;//move PageAddress to Z pointer
sts SpmcrAddr, r10 ;//move spmcrval to SPM control register
spm ;//erase page
#endasm
while (SPMCR&1); //wait for spm complete
spmcrval=5; //write page
#asm
movw r30, r4 ;//move PageAddress to Z pointer
sts SpmcrAddr, r10 ;//move spmcrval to SPM control register
spm ;//write page
#endasm
while (SPMCR&1); //wait for spm complete
spmcrval=0x11; //enableRWW see mega8 datasheet for explanation
// P. 212 Section "Prevent reading the RWW section
// during self-programming
#asm
sts SpmcrAddr, r10 ;//move spmcrval to SPMCR
spm
#endasm
if (CheckFlash()) putchar('!'); //all ok, send next page
else putchar('$'); //there was an error, resend page
} //end if (GetPage())
else putchar('@'); //there was an error ,resend page
// putchar('P'); //there was an error ,resend page
}
}
А результат, прочитанный из контроллера:
Код
:0400000000000000FC
:1000040000000000000000000000000000000000EC
:1000140000000000000000000000000000000000DC
:1000240000000000000000000000000000000000CC
:1000340000000000000000000000000000000000BC
:1000440000000000000000000000000000000000AC
:10005400000000000000000000000000000000009C
:10006400000000000000000000000000000000008C
:100074000000000000000000000000000C0D0E0F46 //вот здесь заканчивается 128 байтная страница
:10008400202020202020202020202020202020206C
:10009400202122232425262728292A2B2C2D2E2FE4 // Дальше почему-то не пишется...
:1000A400303132333435363738393A3B3C3D3E3FD4
:1000B400404142434445464748494A4B4C4D4E4FC4
Помогите найти ошибку.
Когда я испытывал полный код творилась фигня - программа писалась и даже работала. Но при изменении некоторых переменных, значение одних из них в прошивке менялось, другие оставались прежними.
Сообщение отредактировал zheka - Feb 11 2012, 14:11