Jump to content

    
Sign in to follow this  
wmakc

Снижение потребления AT91SAM9

Recommended Posts

Контроллер должен периодически включаться по таймеру, выполнять работу, и уходить в какой-нибудь режим низкого потребления. Также должна быть возможность его пробуждения по Usart. Что нужно для этого сделать?

Share this post


Link to post
Share on other sites
Контроллер должен периодически включаться по таймеру, выполнять работу, и уходить в какой-нибудь режим низкого потребления. Также должна быть возможность его пробуждения по Usart. Что нужно для этого сделать?

по таймеру было бы не плохо проинициализировать на нужную тактовую, пыполнить задачу, и назад переинициализироваться с slow-clock и так со всеми перефириями, при этом читать еррату, что бы не оказались артефакты рядом с вашими перефириями

Share this post


Link to post
Share on other sites
Контроллер должен периодически включаться по таймеру, выполнять работу, и уходить в какой-нибудь режим низкого потребления. Также должна быть возможность его пробуждения по Usart. Что нужно для этого сделать?

 

У Атмела целый документ есть:

http://www.atmel.com/dyn/resources/prod_do...nts/doc6217.pdf

 

Вам нужен suspend mode (или Idle). Только не забудьте корректно подготовить SDRAM к переходу в этот режим ...

Share this post


Link to post
Share on other sites
У Атмела целый документ есть:

http://www.atmel.com/dyn/resources/prod_do...nts/doc6217.pdf

 

Вам нужен suspend mode (или Idle). Только не забудьте корректно подготовить SDRAM к переходу в этот режим ...

вообщето указанный Вами документ предназначен для AT91SAM9261

хотя и с него можно кое что черпнуть ))

Share this post


Link to post
Share on other sites
вообщето указанный Вами документ предназначен для AT91SAM9261

хотя и с него можно кое что черпнуть ))

 

Это не важно, там почти все совпадает. Я по этому документу делал Suspend для AT91SAM9XE512. Естественно, пришлось почитать даташит на этот МК ...

Share this post


Link to post
Share on other sites
Что нужно для этого сделать?

 

Поставить Linux ? suspend to ram там замечательно работает - одной строчки в шелле достаточно, или поучиться на исходниках Linux.

Share this post


Link to post
Share on other sites
У Атмела целый документ есть:

http://www.atmel.com/dyn/resources/prod_do...nts/doc6217.pdf

 

Вам нужен suspend mode (или Idle). Только не забудьте корректно подготовить SDRAM к переходу в этот режим ...

 

Можно поподробнее про подготовку 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 должен возвращаться в активный режим.

Share this post


Link to post
Share on other sites
Можно поподробнее про подготовку 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 "перед сном", если будете снижать частоту его тактирования ...

Share this post


Link to post
Share on other sites
1. Я в своем Кейле в стартап-файле написал, чтобы память переходила в Self Refresh через 64 такта после последнего к ней обращения. Сначала я перестаю обращаться к ОЗУ, затем оно переходит в Self Refresh (осциллограф это подтверждает), а дальше я начинаю переводить МК в Suspend-режим. Я понимаю, что так делать, возможно, не очень красиво - необходимо посылать памяти команду перехода в Self Refresh самому, но как это сделать, я попросту не знаю. А описанное выше решение работает железно.

 

Можно поподробнее про то, как вы переводите память в Self Refresh. Никогда так не делал, поэтому не совсем понимаю как это сделать

Edited by wmakc

Share this post


Link to post
Share on other sites
Можно поподробнее про то, как вы переводите память в Self Refresh. Никогда так не делал, поэтому не совсем понимаю как это сделать

 

Не я перевожу, она сама туда переходит после последнего обращения. Главное контроллер в МК правильно настроить. См. также описание регистра SDRAMC_LPR ...

Low_Power.bmp

Share this post


Link to post
Share on other sites

Немного разобрался, потребление удалось снизить. Только столкнулся с проблемой. Включаю прерывания по USART по заполнению буфера, выключаю ядро. Так оно сразу возвращается в обычный режим. Начал смотреть и заметил, что как только включаю прерывания по USART, так прерывание сразу срабатывает. Даже если нет никакой передачи данных на контроллер. Немогу понять с чем это связано

Share this post


Link to post
Share on other sites
Немного разобрался, потребление удалось снизить. Только столкнулся с проблемой. Включаю прерывания по USART по заполнению буфера, выключаю ядро. Так оно сразу возвращается в обычный режим. Начал смотреть и заметил, что как только включаю прерывания по USART, так прерывание сразу срабатывает. Даже если нет никакой передачи данных на контроллер. Немогу понять с чем это связано

 

Вот, из описания контроллера PDC:

 

"

When the programmed data is transferred, an end of transfer interrupt is generated

by the peripheral itself.

"

 

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

Share this post


Link to post
Share on other sites

не знаю, может и глупый вопрос, но можно ли usart настроить на slow clock, а при срабатывании прерывания перестроить на максимальную скорость? или не перестраивать, но как настроить прерывания?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this