Перейти к содержанию
    


===========IAP.C=============



#include "IAP.h"

#define IAP_CLK Fcclk

#define IAP_LOCATION 0x7FFFFFF1
#define iap_entry(a, B)     ((void (*)())(IAP_LOCATION))(a, B) 

unsigned long command[5] = {0,0,0,0,0};
unsigned long result[3]= {0,0,0};


/*************************************************************************
* Function Name: IAP_PrepareSec
* Parameters: 	unsigned long StartSecNum -- Start Sector Number
*			 	unsigned long EndSecNum -- End Sector Number
* Return: unsigned long -- Status Code 
*
* Description: This command must be executed before executing "Copy RAM to Flash" or
*			"Erase Sector(s)" command.
*
*************************************************************************/
unsigned long IAP_PrepareSec (unsigned long StartSecNum,  unsigned long EndSecNum)
{
if (EndSecNum < StartSecNum)
	return IAP_STA_INVALD_PARAM;

command[0] = IAP_CMD_PrepareSec;
command[1] = StartSecNum;
command[2] = EndSecNum;
iap_entry(command, result);

return result[0];
}

/*************************************************************************
* Function Name: IAP_CopyRAMToFlash
* Parameters: 	unsigned long dst -- Destination Flash address, should be a 256 byte boundary.
*			 	unsigned long src -- Source RAM address, should be a word boundary
*				unsigned long number -- 256 | 512 |1024 |4096			
* Return: unsigned long -- Status Code 
*
* Description: This command is used to program the flash memory.
*
*************************************************************************/
unsigned long IAP_CopyRAMToFlash (unsigned long dst,  unsigned long src, 
unsigned long number)
{
command[0] = IAP_CMD_CopyRAMToFlash;
command[1] = dst;
command[2] = src;
command[3] = number;
command[4] = IAP_CLK / 1000;	// Fcclk in KHz
iap_entry(command, result);

return result[0];
}


/*************************************************************************
* Function Name: IAP_EraseSec
* Parameters: 	unsigned long StartSecNum -- Start Sector Number
*			 	unsigned long EndSecNum -- End Sector Number
* Return: unsigned long -- Status Code 
*
* Description: This command is used to erase a sector or multiple sectors of on-chip Flash
*			 memory.
*
*************************************************************************/
unsigned long IAP_EraseSec (unsigned long StartSecNum,  unsigned long EndSecNum)
{
if (EndSecNum < StartSecNum)
	return IAP_STA_INVALD_PARAM;

command[0] = IAP_CMD_EraseSec;
command[1] = StartSecNum;
command[2] = EndSecNum;
command[3] = IAP_CLK / 1000;
iap_entry(command, result);

return result[0];
}

/*************************************************************************
* Function Name: IAP_BlankChkSec
* Parameters: 	unsigned long StartSecNum -- Start Sector Number
*			 	unsigned long EndSecNum -- End Sector Number
* Return: unsigned long -- Status Code 
*
* Description: This command is used to blank check a sector or mutilple sectors of on-chip
*			  Flash memory.
*
*************************************************************************/
unsigned long IAP_BlankChkSec (unsigned long StartSecNum,  unsigned long EndSecNum,
				unsigned long * pResult)
{
if (EndSecNum < StartSecNum)
	return IAP_STA_INVALD_PARAM;

command[0] = IAP_CMD_BlankChkSec;
command[1] = StartSecNum;
command[2] = EndSecNum;

iap_entry(command, result);

if (result[0] == IAP_STA_SECTOR_NOT_BLANK)
{
	*pResult = result[0];
	*(pResult+1) = result[1];
}

return result[0];
}

/*************************************************************************
* Function Name: IAP_ReadParID
* Parameters: 	unsigned long * PartID
* Return: unsigned long -- Status Code 
*
* Description: This command is used to read the part identification number.
*
*************************************************************************/
unsigned long IAP_ReadParID (unsigned long * PartID)
{

command[0] = IAP_CMD_ReadParID;
iap_entry(command, result);
*PartID = result[1];

return result[0];
}

/*************************************************************************
* Function Name: IAP_ReadBootVer
* Parameters: 	char * MajorVer
*				char * MinorVer
* Return: unsigned long -- Status Code 
*
* Description: This command is used to read the boot code version number.
*
*************************************************************************/
unsigned long IAP_ReadBootVer (unsigned long * MajorVer, unsigned long * MinorVer)
{
command[0] = IAP_CMD_ReadBootVer;
iap_entry(command, result);
*MajorVer = (result[1] & 0xff00)>>8;
*MinorVer = result[1] & 0xff;

return result[0];
}

/*************************************************************************
* Function Name: IAP_Compare
* Parameters: 	unsigned long dst -- Destination Flash address
*			 	unsigned long src -- Source RAM address
*				unsigned long number -- Should be in mutilple of 4		
* Return: unsigned long -- Status Code 
*
* Description: This command is used to compary the memory contents at two locations.
*
* NOTE:	Compary result may not be correct when source or destination address contains
*		any of the first 64 bytes starting from address zero. First 64 bytes can be re-mapped
*		to RAM.
*
*************************************************************************/
unsigned long IAP_Compare (unsigned long dst,  unsigned long src, 
unsigned long number, unsigned long *offset)
{
command[0] = IAP_CMD_Compare;
command[1] = dst;
command[2] = src;
command[3] = number;
iap_entry(command, result);

if (result[0] == IAP_STA_COMPARE_ERROR)
	*offset = result[1];

return result[0];
}

void  IAP_ReinvokeISP(void)
{
command[0] = IAP_CMD_REINVOKEISP;					
iap_entry(command, result);;	
}

=====================================
===========IAP.H=============
#ifndef __IAP_H
#define	__IAP_H

/* IAP Command */
#define		IAP_CMD_PrepareSec		50		//select sector
#define		IAP_CMD_CopyRAMToFlash	51		//copy data from ram to flash
#define		IAP_CMD_EraseSec		52		//erase sector
#define		IAP_CMD_BlankChkSec		53		//check if sector is blank
#define		IAP_CMD_ReadParID		54		//read chip ID
#define		IAP_CMD_ReadBootVer		55		//read BOOT version
#define		IAP_CMD_Compare			56		//compare
#define		IAP_CMD_REINVOKEISP		57		//reinvoke ISP command

/* IAP Status Codes */
#define IAP_STA_CMD_SUCCESS 								0
#define IAP_STA_INVALID_COMMAND 							1
#define IAP_STA_SRC_ADDR_ERROR 								2
#define IAP_STA_DST_ADDR_ERROR 								3
#define IAP_STA_SRC_ADDR_NOT_MAPPED 						4
#define IAP_STA_DST_ADDR_NOT_MAPPED 						5
#define IAP_STA_COUNT_ERROR 								6
#define IAP_STA_INVALID_SECTOR 								7
#define IAP_STA_SECTOR_NOT_BLANK							8
#define IAP_STA_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION 	9
#define IAP_STA_COMPARE_ERROR 								10
#define IAP_STA_BUSY 										11

#define IAP_STA_INVALD_PARAM 								12

extern unsigned long IAP_PrepareSec (unsigned long,  unsigned long);
extern unsigned long IAP_CopyRAMToFlash (unsigned long dst,  unsigned long src, 
unsigned long number);
extern unsigned long IAP_EraseSec (unsigned long StartSecNum,  unsigned long EndSecNum);
extern unsigned long IAP_BlankChkSec (unsigned long StartSecNum,  unsigned long EndSecNum,
				unsigned long * pResult);
extern unsigned long IAP_ReadParID (unsigned long * PartID);						
extern unsigned long IAP_ReadBootVer (unsigned long * MajorVer, unsigned long * MinorVer);
extern unsigned long IAP_Compare (unsigned long dst,  unsigned long src, 
   unsigned long number, unsigned long *offset);
extern void  IAP_ReinvokeISP(void);	


#endif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Позвольте задать вопрос в этой теме касаемо IAP. В мануале на LPC2378, который использую, написанно чёрным по-нерусски: "Up to 512 kB on-chip Flash Program Memory with In-System Programming (ISP) and In-Application Programming (IAP) capabilities. Single Flash sector or full-chip erase in 400 ms and 256 bytes programming in 1 ms". То есть для стирания !одного! или !всех! секторов без разницы надо 400 мс, а для записи 4кб=256*16=16мс? а сколько надо для подготовки сектора к записи и стиранию, и сравнения двух секторов? по этим операциям временных рамок не нашёл.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а сколько надо для подготовки сектора к записи и стиранию
D

В миллисекундном измерении приблизительно "нисколько".

, и сравнения двух секторов?

А это вообще бесполезность - сами можете сравнить - за сколько сравните, за столько и будет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я так и думал :) . А касаемо стирания одного сектора? "Single Flash sector or full-chip erase in 400 ms "

И вообще имеет смысл каждый раз чистить сектор перед употреблением? То есть, не правильно выразился, какова вероятность ошибочной записи сектора без его предворительного стирания?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И вообще имеет смысл каждый раз чистить сектор перед употреблением? То есть, не правильно выразился, какова вероятность ошибочной записи сектора без его предворительного стирания?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

(TanT @ Feb 19 2009, 08:49)

И вообще имеет смысл каждый раз чистить сектор перед употреблением? То есть, не правильно выразился, какова вероятность ошибочной записи сектора без его предворительного стирания?

Глупый вопрос, :blush: Следующий раз буду внимательнее слушать старших товарищей.

 

Однако, всё таки кто-нибудь сможет ответить на вопрос: сколько требуется времени для стирания одного сектора по IAP для LPC2378?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TanT

Однако, всё таки кто-нибудь сможет ответить на вопрос: сколько требуется времени для стирания одного сектора по IAP для LPC2378?

А просто взять и измерить?

1. Таймером - считать значение до входа в процедуру стирания, считать значение после выхода, вывести в UART разницу

2. Осциллом - установить пин из 0 в 1 до входа, из 1 в 0 после выхода

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А просто взять и измерить?

Зачем? Получить некое конкретное зачение для данного чипа в данный момент времени? Что будет у другого экземпляра? Что будет после 1000 стираний? Производитель документирует 400 - их и нужно придерживаться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Производитель документирует 400 - их и нужно придерживаться.

 

Игорь, простите, конечно, настырность, но эти милисекунды очень критичны. Развейте наконец мои сомнения. Сколько времени требуется для стирания одного сектора? А десяти?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сколько времени требуется для стирания одного сектора? А десяти?

Столько, сколько Вы прочитали в документации - любое стирание хоть чипа, хоть одного сектора 400ms. Десять секторов последовательно - в десять раз больше одного сектора. Любые надежды на ускорение и из последствия на Вашей совести. Когда-то давно давно еще на LPC2114 измерения делал - результаты где-то в глубинах форума должны быть. Время стирания помнится много меньше 400ms ну и что? Хотите занятся радиолюбительством? - Измеряйте и занимайтесь :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо большое, именно это хотел услышать.

А радиолюбительством я вроде и не собирался заниматься, не тот случай. ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если уж хочется что-то поделать пока идет стирание, можно разместить функцию в RAM. Если нужны прерывания - мапировать векторы в RAM и разместить в RAM обработчики. У меня так сбрасывается внешний вочдог пока идет стирание.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Позвольте задать вопрос в этой же теме дабы не создавать новой.

Собираюсь писать свой загрузчик под LPC21хх через модуль IAP.

Состоит из программы ПК и программы для контроллер. ПО на ПК будет принимать прошивку в в виде hex файла и отправлять контроллеру через хх интерфейс, допусти 232. Надо ли мне как-то преобразовывать в другой формат прежде чем писать прошивку во флеш, или хватит просто класть по нужным адресам?

 

Ещё вопрос по созданию проектов в IAR

Бутлодер должен висеть в самом начале флеша(первые 4кб), и запускаться первым затем передавать управление основной программе функцией ((void (*)())0x1000)();

Основная программа расположена с адреса 0x1000. Как в данном случае должна происходить работа прерываний для этих разный областей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прилагаю подробную инструкцию по IAP для использования с компилятором Crossworks.

Извиняюсь перед автором этого документа, что не записал его адрес в интернете.

IAP.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прилагаю подробную инструкцию по IAP для использования с компилятором Crossworks.

Извиняюсь перед автором этого документа, что не записал его адрес в интернете.

Спасибо за пример, разбираюсь :)

 

Вопрос по прерываниям в основной программой. Если я линкеру укажу файлик "LPC2148_flash.xcl" в котором ручками поправлю начало флеш

-DROMSTART=00001000

вместо

-DROMSTART=00000040

и прерывания

-Z(CODE)INTVEC=00001000-0000103f

вместо

-Z(CODE)INTVEC=00000000-0000003f

будут ли корректно работать прерывания? Камешек lpc2148

Всем спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...