Цитата(wmakc @ Oct 8 2010, 08:49)

Можно поподробнее про подготовку SDRAM. Когда ее нужно перенастраивать, после перехода в Idle режим? Еще вопрос, посылаю контроллеру команду перехода в этот режим, а он просто зацикливается:
Код
AT91C_BASE_PMC->PMC_SCDR = AT91C_PMC_PCK;
while ((AT91C_BASE_PMC->PMC_SCSR & AT91C_PMC_PCK) != AT91C_PMC_PCK);
Кроме того в документе написано, что в этом режиме отключается только процессор
"In Idle Mode, only the processor clock is stopped and the rest of the device is clocked by the
master clock." Тоесть как я понимаю он должен продолжать реагировать на прерывания. И пре посылке данных по USART должен возвращаться в активный режим.
1. Я в своем Кейле в стартап-файле написал, чтобы память переходила в Self Refresh через 64 такта после последнего к ней обращения. Сначала я перестаю обращаться к ОЗУ, затем оно переходит в Self Refresh (осциллограф это подтверждает), а дальше я начинаю переводить МК в Suspend-режим. Я понимаю, что так делать, возможно, не очень красиво - необходимо посылать памяти команду перехода в Self Refresh самому, но как это сделать, я попросту не знаю. А описанное выше решение работает железно.
2. Вот извлечение из моего проекта - погружение процессора в Suspend, от начала и до конца:
[pre]
/*Low_Power_Mode();*/
//Peripheral Clock Disable
AT91C_BASE_PMC->PMC_PCDR = 0x0000005c; //PIOA, PIOB, PIOC, USART clicking off
//Going to "Slow clock mode":
//MCKR: Program CSS field only
//Master clock = Slow clock (according to Startup-file, Processor clock = Master clock / 2)
AT91C_BASE_PMC->PMC_MCKR &= 0xfffffffc;
//Wait until Main Master Clock is ready
while(!(AT91C_BASE_PMC->PMC_SR & 0x00000008)){};
//Program all fields
AT91C_BASE_PMC->PMC_MCKR = 0x00000200; //Processor clock = Slow clock,
//Master clock = Processor clock / 4
//Wait until Main Master Clock is ready
while(!(AT91C_BASE_PMC->PMC_SR & 0x00000008)){};
//PLLA off
*AT91C_CKGR_PLLAR = 0x20000000;
////////////////////////
AT91C_BASE_PMC->PMC_SCDR = 0x00000001; //Processor Clock off
sbz = 0;
__asm{MCR p15, 0, sbz, c7, c0, 4}
//Проснулись ! Теперь надо все восстановить:
Normal_Power_Mode();
[/pre]
Да, именно так, будет возвращаться, но не сам собой. Вы должны будете после пробуждения процессора вручную все повключать, восстановить частоты и вернуть все "на круги своя":
[pre]
void Normal_Power_Mode(void)
{
//Peripheral Clock Enable
AT91C_BASE_PMC->PMC_PCER = 0x0000005c; //PIOA, PIOB, PIOC, USART clocking on
//Setup the PLL A
*AT91C_CKGR_PLLAR = 0x20B3BF0C;
//Wait until PLL A is stabilized
while(!(AT91C_BASE_PMC->PMC_SR & 0x00000002)){};
//Program PRES field only
AT91C_BASE_PMC->PMC_MCKR &= 0xffffffe3; //Processor clock = Slow clock
//Wait until Main Master Clock is ready
while(!(AT91C_BASE_PMC->PMC_SR & 0x00000008)){};
//Program all fields
AT91C_BASE_PMC->PMC_MCKR = 0x00000102; //Processor clock = PLLA,
//Master clock = Processor clock / 2
//Wait until Main Master Clock is ready
while(!(AT91C_BASE_PMC->PMC_SR & 0x00000008)){};
}
[/pre]
Кстати, не забудьте перенастроить UART "перед сном", если будете снижать частоту его тактирования ...