|
Конкретно, что не понятно? В даташите на Мегу 128 все расписано нормально. Вот мой работающий кусок - вначале идет всякая преамбула, потом (с которого начинается приведеная вставка) - загрузка 2х байт длины массива (В СЛОВАХ!!!) потом такой финт - прием байт ведется по прерываниям в приемный буфер УАРТА (векторы перенесены в бут-сектор), причем если до конца буфера остается меньше 20-ти байт, RTS сбрасывается, тормозя порт. Когда основная прога выгребает данные, и буфер освобождается более, чем на 60 байт - RTS взводится вновь. rx_counter - сколько байт в приемном буфере УАРТа. page_buffer - буфер для программирования флеша. Ну далее все понятно, я думаю (если и щас непонятно - тогда не стОит и продолжать ;-))
Преимущества прерываний: буфер страницы 256 байт (128 слов) при скорости 115200 бод заполняется за 22мс. А запись страницы флеша - 4мс на стирание + 4мс на саму запись, + пару-тройку мс на всякие заполнения-проверки, т.е. примерно 10мс. Получается прочессы закачки данных и записи их во флеш идут параллельно, СОМ-порт "дует" данные непрерывно. Если б скорость СОМ-порта писюка поднять до 230400 - очень красяво бы вышло, 11 мс страница, или вся 128-я Мега за 1,5 секунды! (Ау, ISP-шники?... :-))))
(да и сейчас неплохо)
(Примечание - если код подпортится из-за всяких "тегов" - я не виноват. Среда - ИАР 3.10С)
// Принята синхропоследовательность + 'F'. Загрузка данных
// и программирование FLASH
data_counter = 0; tempchar = 0; // количество записанных в буфер страницы байт if (tempchar) // остались байты? // загрузка FLASH окончена - беск. цикл и
E-mail:
info@telesys.ru
data_lenth = 0; // in WORDS!!! (0000-F000)
if ((tempint = Receive_Byte_UDR1()) & (1<<(FE1+8))) Fatal_Error();
data_lenth |= (unsigned int)((char)tempint);
if ((tempint = Receive_Byte_UDR1()) & (1<<(FE1+8))) Fatal_Error();
data_lenth |= ((unsigned int)((char)tempint)<<8);
if (data_lenth >= 0xF000) Fatal_Error(); // нельзя писАть в BootSector!
// теперь прием в прерываниях по RXC1
// Enable RXC1 Interrupt
UCSR1B = (1<
flash_address = 0; // адрес следующей (0) страницы в словах
RAMPZ = 0; //RAMPZ = 0 (все начинается с нулевой страницы)
while (data_counter != data_lenth) // цикл записи во FLASH
{
while (buffer_head == buffer_tail); // ждать, если нечего записывать
page_buffer[tempchar++] = input_buffer[buffer_tail++];
while (buffer_head == buffer_tail); // ждать, если нечего записывать
page_buffer[tempchar++] = input_buffer[buffer_tail++];
__disable_interrupt();
if ((rx_counter -= 2) < (0xFF-60))
{
PORTD &= ~(1<
}
__enable_interrupt();
data_counter++; // in WORDS!!!
if (tempchar) continue; // если страница не заполнена полностью
// Запись!
write_flash_page (); //RAMPZ + flash_address + page_buffer[256] !
flash_address = data_counter<<1; // адрес следующей страницы в словах
RAMPZ = (char)(data_counter>>15);
}
{
while (tempchar)
{
// дозаполнить страницу 0xFF
page_buffer[tempchar++] = 0xFF;
page_buffer[tempchar++] = 0xFF;
}
write_flash_page (); //RAMPZ + flash_address + page_buffer[256] !
}
Ответы