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

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

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

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


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

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

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

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


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

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

 

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

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

 

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

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


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

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

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

 

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

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

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

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


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

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

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

 

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

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


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

Что нужно для этого сделать?

 

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

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


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

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

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

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


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

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

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


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

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

 

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

Изменено пользователем wmakc

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


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

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

 

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

Low_Power.bmp

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


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

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

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


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

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

 

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

 

"

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

by the peripheral itself.

"

 

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

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


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

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

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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