ATTiny2313: использование инструкции SPM

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс янв 31, 2010 17:16:17

Сообщение eqltv »

Хочу использовать память программ для долговременного хранения данных. Почитал AVR109 про самопрошивку и написал такой код (привожу только ту часть, которая пытается работать с памятью программ):

Код: Выделить всё

	; Считать байт и проверить его на равенство 0xff
	ldi	r30, lo8(1024)
	ldi	r31, hi8(1024)
	lpm
	inc	r0
	brne	end

	; заполнить таблицу словом 0xaa55
	ldi	r18, 0x55
	ldi	r19, 0xaa
	mov	r0, r18
	mov	r1, r19
	ldi	r19, PGSIZE
l1:	ldi	r18, 1
	out	SPMCSR, r18
	spm
	adiw	r30, 2
	dec	r19
	brne	l1
	; записать
	ldi	r30, lo8(1024)
	ldi	r31, hi8(1024)
	ldi	r18, 5
	out	SPMCSR, r18
	spm
end:		
	rjmp	end
Ожидается, что в 16 словах с адреса 1024 будет записано 0xAA55. Но они остаются незапрограммированными.
Кроме того, возник вопрос про "bootloader". В описании tiny2313 совсем ничего о нем не сказано, а фьюзы, которыми он управляется, помечены неиспользуемыми. Но про самопрограммирование там есть - запись в любую область памяти останавливает процессор на время записи, как будто вся память образует этот bootloader.
Помогите разобраться и понять, почему не работает код.
Реклама
GP1
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград

Сообщение GP1 »

Если я ничего не путаю, вот так из текста программы использовать SPM не получится.
Чем дальше, тем больше становлюсь занудой...
Изображение
Контактная информация:
Реклама
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс янв 31, 2010 17:16:17

Сообщение eqltv »

GP1 писал(а):Если я ничего не путаю, вот так из текста программы использовать SPM не получится.
А как получится? Откуда ее вызывать, если в даташите ничего про бутлоадер не сказано?
Родился
Сообщения: 8
Зарегистрирован: Чт янв 28, 2010 16:27:21

Сообщение uchar »

Могу ошибаца, но мое предположение такое - записывая в регистр Z адрес ячейки, начиная с которой хотите писать свои данные, надо сдвинуть адрес на 1 влево :

Код: Выделить всё

ldi		ZL,Low (SerialN<<1)
ldi		ZH,High(SerialN<<1)
А дальше после записи каждого байта делать инкремент Z.

Тут все дело в том, что в регистре Z 15 старших бит указывают на адрес ячейки, а младший бит указывает на то, старший или младший байт ячейки вы будете читать/писать.

Полагаю, что сейчас вы пишете во флэш, но только совсем ну туда, куда хотите. У меня все было именно так, только при чтении :)
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс янв 31, 2010 17:16:17

Сообщение eqltv »

Написал на C программу (avr-libc) - тоже не работает. Вот код:

Код: Выделить всё

BOOTLOADER_SECTION
void fillPage(unsigned int addr, unsigned int word)
{
	int i;
	for(i = 0; i < SPM_PAGESIZE; i+=2)
	{
		boot_page_fill(addr + i, word);
	}
}

BOOTLOADER_SECTION
void writePage(unsigned int addr)
{
	boot_page_write(addr);
	boot_spm_busy_wait();
	//boot_rww_enable();
}

BOOTLOADER_SECTION
void erasePage(unsigned int addr)
{
	boot_page_erase(addr);
	boot_spm_busy_wait();
}

int main()
{
	unsigned char b = 0;
	unsigned int addr = 0;
	unsigned int pgaddr = 0;
	lptInit();
	while(1)
	{
		b = lptRecv(0xcc);
		addr = 0;
		switch(b)
		{
			case 1: // lpm
				addr |= lptRecv(0xa0);
				addr |= lptRecv(0xa1)<<8;
				lptSend(pgm_read_byte_near(addr));
				break;
			case 2: // set page address
				addr |= lptRecv(0xa0);
				addr |= lptRecv(0xa1)<<8;
				pgaddr = addr;
				break;
			case 3: // fill page with word
				addr |= lptRecv(0xd0);
				addr |= lptRecv(0xd1)<<8;
				fillPage(pgaddr, addr);
				break;
			case 4: // write page
				writePage(pgaddr);
				break;
			case 5: // erase page
				erasePage(pgaddr);
				break;
			case 6: // lpm 2 bytes from pgaddr
				lptSend(pgm_read_byte_near(pgaddr));
				lptSend(pgm_read_byte_near(pgaddr+1));
				break;
			default:
				break;
		}
	}
	return 0;
}

lpt* - это команды общения с компьютером. Всё работает правильно, кроме записи во флэш. Пытался даже просто стереть страницу с адресом 0, не стерлась.
Почему не работает? Как заставить?
Реклама
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс янв 31, 2010 17:16:17

Сообщение eqltv »

Всё, проблема решена. Нужно было запрограммировать бит SELFPRGEN(0) из efuse. Выводы - нужно читать весь даташит, а не только отдельную главу.
Реклама
Родился
Сообщения: 8
Зарегистрирован: Чт янв 28, 2010 16:27:21

Сообщение uchar »

Перечитал документацию ешо раз - все написанное мной выше относица только к чтению данных из флэша, т.е. к команде LPM.
При записи все будет иначе.
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»