реклама на сайте
подробности

 
 
> Алгоритм программирования FLASH памяти Atmega48, по SPI
algidim
сообщение May 11 2012, 11:15
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 160
Регистрация: 5-04-06
Из: Москва
Пользователь №: 15 847



Здравствуйте ! В устройстве 2 микроконтроллера LPC1768 второй вспомогательный atmega48, хочется сделать так чтобы при начальной заливке или обновлении прошивки LPC1768 автоматически программировал atmega48… Т.е нужно написать программатор для atmega 48. Atmega48 подключена по SPI + вывод reset
Не могу разобраться с алгоритмом программирования FLASH памяти – читать память получается а вот записывать не очень )) Читаю по командам $28 (старший байт) $27 (младший байт).
Записывать я так понял там нужно по командам $40 и $48 в страницу памяти а потом по команде $4C переписывать во FLASH память.

Смотрел исподники avr910 там пишется байт по команде $40 и $48 а потом сразу же проверяется его запись, т.е читается по команде $28 и $27 . У меня при чтении читается байт, который там записан ( проверка реальным программатором ) а вот команды $40 и $48 получается проходят в холостую ))
Может кто подскажет алгоритм программирования Flash памяти ? или поделится исходником, где это понятно…
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
algidim
сообщение May 11 2012, 11:54
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 160
Регистрация: 5-04-06
Из: Москва
Пользователь №: 15 847



Цитата(KRS @ May 11 2012, 15:27) *
откопал свой программатор через старый FTDI bit bang (еще асинхронный)

Спасибо ! Сейчас попробую - кое чего понятно, т.е писать обязательно целой страницей ? А если мне нужно допустим записать 2 байта ))) все равно нужно писать целую страницу, просто остальные байты нужно в 0xFF установить ?
Go to the top of the page
 
+Quote Post
KRS
сообщение May 11 2012, 12:08
Сообщение #3


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(algidim @ May 11 2012, 15:54) *
т.е писать обязательно целой страницей ? А если мне нужно допустим записать 2 байта ))) все равно нужно писать целую страницу, просто остальные байты нужно в 0xFF установить ?

да.
Go to the top of the page
 
+Quote Post
prottoss
сообщение May 11 2012, 12:32
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(KRS @ May 11 2012, 18:08) *
да.
Нет. Не вводите человека в заблуждение. Если нужно записать байт меньше, чем размер страницы, нужно завершить запись командой записи страницы.

Вообще программирование очень подробно и внятно описано в разделе Serial Programming Algorithm любого МК AVR

Вот моя реализация алгоритма. Может сложно с наскоку, но, по крайней мере с комментами, так что должно быть понятно

CODE
/* Write memory parameters */
#pragma pack(ALIGN_INT8)
typedef struct __ISP2_WRITE_MEM_PARAM
{
UINT8 cmd_id; /* Command ID */
UINT16 num_bytes; /* Total number of bytes to program, LSB first */
UINT8 mode; /* Programming mode */
UINT8 delay; /* Delay, used for different types of programming termination,
according to mode byte */
UINT8 cmd_WrMem; /* Command 1 - Load Page, Write Programm Memory */
UINT8 cmd_WrPgm; /* Command 2 - Write Programm Memory Page */
UINT8 cmd_RdMem; /* Command 3 - Read Programm Memory */
UINT8 poll_1; /* Poll value 1 */
UINT8 poll_2; /* Poll value 2 - not using for flash programming */
UINT8 data[1]; /* Data array */

} ISP2_WRITE_MEM_PARAM, *P_ISP2_WRITE_MEM_PARAM;
#pragma pack()

/*******************************************************************************
*******************************************************************************/
static INT CMD_WriteMem(P_ISP2_WRITE_MEM_PARAM param, INT msg_len, UINT8 mem_type)
{
UINT8 byte, cmd[4], data[4];
UINT8 val_poll, rdy_poll;
INT i;

/* Check parameters */
if(msg_len < sizeof(ISP2_WRITE_MEM_PARAM) || /* Wrong message */
g_ISP2.state != ISP2_IN_PROG_STATE) /* Illegal programmer state */
return ISP2_STATUS_CMD_FAILED;

/* Get parameters */
param->num_bytes = SWAP16(param->num_bytes); /* Correct number of bytes read */

/* Make polling flags */
if(ISP2_WRMEM_MODE_PAGE & param->mode) /* Page mode */
{
val_poll = ISP2_WRMEM_MODE_PAGE_VALUE_POLL;
rdy_poll = ISP2_WRMEM_MODE_PAGE_READY_POLL;
}
else /* Word mode for flash, byte mode for eeprom */
{
val_poll = ISP2_WRMEM_MODE_WORD_VALUE_POLL;
rdy_poll = ISP2_WRMEM_MODE_WORD_READY_POLL;
}

/* Check delay value */
if(!param->delay)
param->delay = ISP2_CFG_DEF_WRITE_DELAY;

/* Check extended address for FLASH programming */
if(ISP2_MEM_TYPE_FLASH == mem_type && g_ISP2.prog_addr & 0x80000000)
{
cmd[0] = 0x4d; /* Load Extended Address command */
cmd[1] = 0x00;
cmd[2] = LOBYTE(HIWORD(g_ISP2.prog_addr));
cmd[3] = 0x00;
ISP_Tx(cmd, 32); /* Send extended address byte */
}

/* Write cycle */
for(i = 0; i < param->num_bytes; i++)
{
/* Load address and data byte */
cmd[1] = LOWORD(HIBYTE(g_ISP2.prog_addr));
cmd[2] = LOWORD(LOBYTE(g_ISP2.prog_addr));
cmd[3] = param->data[i];
byte = cmd[3];

/* Check memory type and make command byte */
if(ISP2_MEM_TYPE_FLASH == mem_type)
{
/* Make command byte (Load Page, Write Program Memory) &
increment address if hi byte writing */
if(i & 0x01)
{
cmd[0] = param->cmd_WrMem | 0x08; /* Make command for hight byte */
g_ISP2.prog_addr++; /* Increment address */
}
else
cmd[0] = param->cmd_WrMem & ~0x08; /* Make command for low byte */
}
else /* EEPROM */
{
cmd[0] = param->cmd_WrMem;
g_ISP2.prog_addr++; /* Increment address */
}

ISP_Tx(cmd, 32); /* Send command */

/* In page mode after send last byte need send command WRITE PAGE */
if(ISP2_WRMEM_MODE_PAGE & param->mode) /* Page mode */
{
if(i < param->num_bytes - 1 || !(ISP2_WRMEM_MODE_PAGE_WRITE_ENABLE & param->mode))
continue; /* It's not last byte or write page bit not set */

cmd[0] = param->cmd_WrPgm; /* Make Write Program Page command */
ISP_Tx(cmd, 32); /* Send PAGE WRITE command */
}

/* Check write success */
if(param->mode & val_poll) /* Value polling */
{
if((byte == param->poll_1) || /* Does not use polling if value is some for polling values */
(ISP2_MEM_TYPE_EEPROM == mem_type && byte == param->poll_2)) /* poll #2 use only EEPROM */
BOARD_DelayMS(param->delay);
else
{
/* Make READ command */
if(ISP2_MEM_TYPE_FLASH == mem_type)
{
if(i & 0x01) /* Make Read Program Memory command */
cmd[0] = param->cmd_RdMem | 0x08; /* Read hight byte */
else
cmd[0] = param->cmd_RdMem & ~0x08; /* Read low byte */
}
else
cmd[0] = param->cmd_RdMem;

/* Wait, when value was write complete */
BOARD_SetTimeout(param->delay);
do
{
ISP_Ex(cmd, data, 32); /* Send command */
if(BOARD_IsTimeout())
return ISP2_STATUS_CMD_TOUT;
}
while(data[3] != byte);
}
}
else
{
if(param->mode & rdy_poll) /* RDY/BSY polling */
{
if(FALSE == WaitReady(param->delay))
return ISP2_STATUS_CMD_TOUT;
}
else /* Timed delay */
BOARD_DelayMS(param->delay);
}
}
return ISP2_STATUS_CMD_OK;
}


Это общий алгоритм для ВСЕХ AVR. Все зависит от параметров.


--------------------
Go to the top of the page
 
+Quote Post
KRS
сообщение May 11 2012, 12:41
Сообщение #5


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(prottoss @ May 11 2012, 16:32) *
Нет. Не вводите человека в заблуждение. Если нужно записать байт меньше, чем размер страницы, нужно завершить запись командой записи страницы.

флешь пишется только по страницам и не записанные в буфер байты не обязательно будут 0xff
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 06:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01413 секунд с 7
ELECTRONIX ©2004-2016