|
Atmel SAM3U4, Различные вопросы |
|
|
|
Jun 26 2011, 18:46
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Доброго времени суток! Начал потихоньку осваивать SAM3U4C, сделал темку, так как возникают различные вопросы, которые хотелось бы обсудить.
В этом камне, не смотря на два банка, RAM можно использовать как единый блок по адресам 0x20078000 - 0x20083FFF.
Можно ли такую же методику применить к флеш? В комплекте с ИАРом идёт флешлоадер, который шьёт сразу два банка по адресам 0x000E0000 - 0x0011FFFF.
Сделал в .icf файле также, посмотрим, как получится на практике, если вместо 0x00080000 везде в программе использовать 0x000E0000.
Ещё хотел спросить про встроенный RTC, если кто им пользовался.
Я так понял, что модифицировать время тут не так просто - надо сначала остановить часы, записать новые значения, запустить их, и подождать около 1 секунды, пока можно будет проводить следующую модификацию. Вот что интересно - после записи и запуска часов сбрасывается ли прескалер секунд? То есть переход на следующую секунду наступит ровно через секунду после запуска, или раньше, в зависимости от значения прескалера?
|
|
|
|
|
Jun 26 2011, 19:17
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jun 26 2011, 22:46)  Можно ли такую же методику применить к флеш? Теоретически ничего не мешает. Цитата(sonycman @ Jun 26 2011, 22:46)  Вот что интересно - после записи и запуска часов сбрасывается ли прескалер секунд? То есть переход на следующую секунду наступит ровно через секунду после запуска, или раньше, в зависимости от значения прескалера? Это так принципиально? Я бы думал, что сбрасывается, а вообще - проверьте.
|
|
|
|
|
Jun 26 2011, 21:03
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jun 26 2011, 23:17)  Это так принципиально? Я бы думал, что сбрасывается, а вообще - проверьте. Привык пользоваться отдельными ИС для RTC, в частности DS3231 позволяет совершенно не заморачиваться с записью, там всё реализовано прозрачно. Теперь же придётся вводить ограничения в интерфейсе при установке времени, то есть городить некий огород...  Да, придётся испытывать, плохо, если при установке, допустим, минут, будут сбрасываться секунды, ну да ладно. Ещё интересно, сможет ли RTC сэма хоть как то приблизиться к точности в +- 2 ppm DS3231?
|
|
|
|
|
Jun 26 2011, 21:07
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jun 27 2011, 01:03)  Привык пользоваться отдельными ИС для RTC, в частности DS3231 позволяет совершенно не заморачиваться с записью, там всё реализовано прозрачно. Теперь же придётся вводить ограничения в интерфейсе при установке времени, то есть городить некий огород...  Огород там совсем небольшой, написать один раз и забыть. Цитата(sonycman @ Jun 27 2011, 01:03)  Да, придётся испытывать, плохо, если при установке, допустим, минут, будут сбрасываться секунды, ну да ладно. Конечно будут - они же в одном регистре  Цитата(sonycman @ Jun 27 2011, 01:03)  Ещё интересно, сможет ли RTC сэма хоть как то приблизиться к точности в +- 2 ppm DS3231? Не знаю. Мне вообще откровенно не понравилось поведение батарейного блока 3U.
|
|
|
|
|
Jun 27 2011, 01:37
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jun 27 2011, 01:07)  Конечно будут - они же в одном регистре  Ну я же сначала вычитаю содержимое всех регистров времени\даты, прежде чем их модифицировать  Но внесение погрешности даже в пределах одной секунды не есть хорошо, хотелось бы такого избежать. Цитата Не знаю. Мне вообще откровенно не понравилось поведение батарейного блока 3U. А можно подробнее? Вы часто сначала обмолвитесь про что-либо интересное, но потом таинственно замолкаете... Жаль, что Атмел не встроили два диода для переключения питания с VDD на VBAT при исчезновении первого, как в тех же STM32...
|
|
|
|
|
Jun 27 2011, 02:35
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jun 27 2011, 05:37)  Но внесение погрешности даже в пределах одной секунды не есть хорошо, хотелось бы такого избежать. ИМХО, это уже излишний перфекционизм. Цитата(sonycman @ Jun 27 2011, 05:37)  А можно подробнее? Могу сказать только, что я как минимум трижды наблюдал зависание этого блока - дважды на атмеловском EK и один раз на своей железке. EK зависал оба раза после прогулки по морозу (сразу оговорюсь, что питание RTC при этом точно не страдало, а температура платы не снижалась ниже 0).
|
|
|
|
|
Jun 29 2011, 15:48
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Да, в даташите довольно много ошибок\опечаток и неточностей  Например, сказано, что чип имеет восемь General Purpose Backup Registers (GPBR), то есть восемь 32 битных регистров с батарейным питанием. Однако адреса приводятся только для четырёх: 0x400E1290 [0], 0x400E1294 [1], 0x400E1298 [2], 0x400E129C [3] Надеюсь, что их всё же восемь - то есть 32 байта. Поменьше, конечно, чем в STM32 High Density Devices, но всё же более менее
|
|
|
|
|
Jun 29 2011, 17:13
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jun 29 2011, 21:03)  Увы, атмеловцы этим грешат. Скажем, описание HSMCI иначе как куцым назвать нельзя. Приходится заниматься исследовательской работой. Да уж. Я некоторое время не мог понять, каким боком работа батарейного блока (в частности контроллера сброса) может зависеть от напряжения VDDUTMI (это USB) ??? Только спустя некоторое время дошло, что имеет место банальная путаница. Теперь уже не считаю такой даташит как истину в последней инстанции. Но сейчас этим грешат многие, и ST, и даже NXP. Поскорее бы обновили документацию на сайте Атмела, может, поправят чего нибудь. Кстати, тоже буду ковырять HSMCI в плане сопряжения с SD картой. Надеюсь на Вашу помощь, если что Там, к слову, в режиме с DMA, можно ли считывать сектора в память, задав один большой буфер? По доке вроде показалось что нет, и надо кроить linked list дескрипторов для каждого сектора...
|
|
|
|
|
Jun 29 2011, 17:31
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jun 29 2011, 21:13)  Кстати, тоже буду ковырять HSMCI в плане сопряжения с SD картой. Надеюсь на Вашу помощь, если что  Это пожалуйста  Цитата(sonycman @ Jun 29 2011, 21:13)  Там, к слову, в режиме с DMA, можно ли считывать сектора в память, задав один большой буфер? По доке вроде показалось что нет, и надо кроить linked list дескрипторов для каждого сектора...  Можно, хотя я не пользовался. Для каждого сектора никакого linked list не нужно, только для группы.
|
|
|
|
|
Jun 29 2011, 17:41
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jun 29 2011, 21:31)  Это пожалуйста  Спасибо!  Цитата(aaarrr @ Jun 29 2011, 21:31)  Можно, хотя я не пользовался. Для каждого сектора никакого linked list не нужно, только для группы. Вот для группы я и имел ввиду. Показалось, что набор регистров управления MCI весьма внушительный, можно задать и кол-во секторов, и их размер, так зачем ещё и нарезать дескрипторы для DMA? Можно было бы задать ему задание, к примеру, в виде считывания 16 секторов по 512 байт в линейный буфер размером 8к, и пусть себе занимается. Зачем для линейного буфера задавать кучу дескрипторов и списков?
|
|
|
|
|
Jun 29 2011, 17:46
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jun 29 2011, 21:41)  Вот для группы я и имел ввиду. Показалось, что набор регистров управления MCI весьма внушительный, можно задать и кол-во секторов, и их размер, так зачем ещё и нарезать дескрипторы для DMA?
Можно было бы задать ему задание, к примеру, в виде считывания 16 секторов по 512 байт в линейный буфер размером 8к, и пусть себе занимается. Зачем для линейного буфера задавать кучу дескрипторов и списков? На самом деле, никто не мешает сделать один большой буфер - со стороны DMA разницы никакой не будет. А пример они просто привели более универсальный. Скажем, в моем случае при записи linked list нужен, так как из-за особенностей построения буферизации сектора могут располагаться в памяти произвольно.
|
|
|
|
|
Jun 29 2011, 17:59
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jun 29 2011, 21:46)  На самом деле, никто не мешает сделать один большой буфер - со стороны DMA разницы никакой не будет. А пример они просто привели более универсальный. А, ну тогда это другое дело, тогда это гораздо веселее  ЗЫ: чёрт, привык уже к STM32, что под ресетом у них пины подтягиваются вниз, к земле, а на сэме наоборот - вверх, к VDD, а это у меня активный уровень  Вот бы вендоры сделали не поленились в будущих чипах конфигурирование подтягивающих резисторов к любому плечу по выбору
|
|
|
|
|
Jul 1 2011, 14:29
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jul 1 2011, 18:13)  В Sleep Mode отключается HCLK, память и шины тактируются от MCK. Отлично, тогда отправлять CPU в сон, загрузив DMA по самые гланды, ничего не помешает  Цитата Нет, не пробовал. К табличкам нужно относится осторожнее, как мы знаем  Это верно! Блин, чем больше читаю мануал, тем больше кажется, что американцы не далеко ушли от русских в плане раздолбайства (в основном, правда, при написании документации). Вот ещё один момент:
и цитата из текста: Цитата The Master Clock Controller is made up of a clock selector and a prescaler. It also contains a Master Clock divider which allows the processor clock to be faster than the Master Clock. Каким образом клок процессора может быть не то что быстрее, а вообще хоть как то отличаться от мастер клока, не понятно
|
|
|
|
|
Jul 4 2011, 10:10
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Провозился вчера весь день с блоком таймеров, реализовывая свою задумку сформировать путём соединения цепочкой один 32 битный таймер с разрешением в 1 микросекунду. Сделал так: TC0->TC1->TC2, выход TC0 (TIOA0) завожу на вход TC1, а выход TC1 (TIOA1) завожу на вход TC2. TC0: играет роль прескалера с входной частотой MCK\2, равной 48 МГц, по событию RA Compare (RA = 24) выход TIOA0 устанавливается в 1, по событию RC Compare (RC = 47) счётчик сбрасывается и выход TIOA0 сбрасывается в 0, получаем меандр с частотой 1 МГц. TC1: младшая половинка 32 битного счётчика, по событию RA Compare (RA = 0xFFFF) выход TIOA1 устанавливается в 1, по событию RC Compare (RC = 0) счётчик сбрасывается и выход TIOA1 устанавливается в 0, получаем импульсы с частотой 1/65536 МГц. Но тут оказалась первая непонятка - такая конфигурация давала инкремент старшей половины 32 битного счётчика сразу по достижении 0xFFFF младшей, что есть переход выглядел так: 0x0000FFFE->0x0001FFFF->0x00010000. Чего я как то не ожидал, поэтому угрохал на вычисление проблемы целый день  Пришлось задать настройки для компараторов вот так: TC1: младшая половинка 32 битного счётчика, по событию RA Compare (RA = 0) выход TIOA1 устанавливается в 1, по событию RC Compare (RC = 0x8000) счётчик сбрасывается и выход TIOA1 устанавливается в 0, получаем меандр с частотой 1/65536 МГц. Ну а последний счётчик TC2 является старшей половинкой получившегося 32 битного регистра и просто тупо инкрементируется 0->0xFFFF безо всяких компараторов. По мере тестов теперь возникла ещё одна проблема - таймер немного "бежит", за час на минуту-другую. Оценка грубая, но видно это хорошо. Отсюда возникли вопросы к "прескалеру" на базе TC0, который должен считать от 0 до 47 и снова с 0 до 47, но, вероятно, считает от 0 до 46, а на 47 происходит сброс сразу на 0, отсюда получаем "бегущий" таймер. Пока что это предположение, надо будет проверить его на практике. В мануале, жать, не приводятся точные цифры по различным режимам счётчиков...
|
|
|
|
|
Jul 4 2011, 11:22
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jul 4 2011, 14:10)  Пришлось задать настройки для компараторов вот так: TC1: младшая половинка 32 битного счётчика, по событию RA Compare (RA = 0) выход TIOA1 устанавливается в 1, по событию RC Compare (RC = 0x8000) счётчик сбрасывается и выход TIOA1 устанавливается в 0, получаем меандр с частотой 1/65536 МГц. На самом деле, достаточно было бы просто отинвертировать входной клок для TC2 (бит CLKI). Цитата(sonycman @ Jul 4 2011, 14:10)  Ну а последний счётчик TC2 является старшей половинкой получившегося 32 битного регистра и просто тупо инкрементируется 0->0xFFFF безо всяких компараторов. А здесь все же был бы уместен программный счетчик. Но хозяин - барин. Цитата(sonycman @ Jul 4 2011, 14:10)  Отсюда возникли вопросы к "прескалеру" на базе TC0, который должен считать от 0 до 47 и снова с 0 до 47, но, вероятно, считает от 0 до 46, а на 47 происходит сброс сразу на 0, отсюда получаем "бегущий" таймер. Нет, он обязан считать до 47. Цитата(sonycman @ Jul 4 2011, 14:10)  В мануале, жать, не приводятся точные цифры по различным режимам счётчиков...  Не понял, какие цифры? Все же не понимаю вашу систему. Зачем такое сумасшедшее разрешение? А еще ведь при чтении счетчика придется проверять граничные условия с запретом прерываний и корректировать при необходимости старшее слово.
|
|
|
|
|
Jul 4 2011, 12:37
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jul 4 2011, 16:29)  Цифры значений счетчика, потактово,чтобы было понятно на 100%, когда происходит инкремент/сброс и т.п, иначе лично у меня возникли неясности... Так из картинок и текста все в общем-то понятно, они его давно уже копипастят  Цитата(sonycman @ Jul 4 2011, 16:29)  Считывать половинки действительно приходится несколько раз (старшую половину), но запрещать прерывания не нужно. Если прерывания гарантированно укладываются в 65мс, то не нужно.
|
|
|
|
|
Jul 4 2011, 14:41
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jul 4 2011, 17:28)  Странно...  Всё законно  : Цитата Note: In all cases, if an external clock is used, the duration of each of its levels must be longer than the master clock period. The external clock frequency must be at least 2.5 times lower than the master clock В вашем случае это условие нарушается - импульс слишком короткий.
|
|
|
|
|
Jul 4 2011, 16:25
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jul 4 2011, 18:41)  В вашем случае это условие нарушается - импульс слишком короткий. Понятно, спасибо  Что-то не подумал, что это "внешний" сигнал... Теперь осталось только выяснить, почему счётчик "бежит" вперёд на две минуты в час. Хз, может быть, косячу при замере, а может дебаггер как то влияет (через него смотрю состояние переменных/регистров)...
|
|
|
|
|
Jul 4 2011, 21:46
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jul 4 2011, 15:22)  Нет, он обязан считать до 47. А вот и нет! На практике оказалось не так! Уже был уверен, после Ваших слов, что глюк с "убеганием" таймера вносит мой софт, но всё же когда пришёл с работы решил прогнать простенький цикл и сохранить значения счётчика TC0 на протяжении его цикла так: Код byte dbuf[4096]; for (int i = 0; i < sizeof(dbuf); i++) { dbuf[i] = (byte)AT_TC0->TC_CV; } то есть считав все его значения на протяжении относительно большого времени. Напомню, конфигурация счётчика была такая: Код AT_TCB0->TCB_TC0.TC_CMR = AT_TC_CLKS_TIMER_DIV32_CLOCK | AT_TC_WAVESEL_UP_AUTO | AT_TC_WAVE | AT_TC_ACPA_SET | AT_TC_ACPC_CLEAR; //| AT_TC_ASWTRG_CLEAR; AT_TCB0->TCB_TC0.TC_RA = 24; AT_TCB0->TCB_TC0.TC_RC = 48; то есть upcounter со сбросом по RC compare, RC = 48(!). И что же получил: Код 00 00 00 01 01 01 01 02 02 02 02 03 03 03 03 04 04 04 04 05 05 05 05 06 06 06 06 06 07 07 07 08 08 08 08 08 09 09 09 09 0a 0a 0a 0a 0b 0b 0b 0b 0c 0c 0c 0c 0d 0d 0d 0d 0e 0e 0e 0e 0e 0f 0f 0f 10 10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 14 15 15 15 16 16 16 16 16 17 17 17 17 18 18 18 18 19 19 19 19 1a 1a 1a 1a 1b 1b 1b 1b 1c 1c 1c 1c 1c 1d 1d 1d 1e 1e 1e 1e 1e 1f 1f 1f 1f 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 25 26 26 26 27 27 27 27 27 28 28 28 28 29 29 29 29 2a 2a 2a 2a 2b 2b 2b 2b 2c 2c 2c 2c 2d 2d 2d 2d 2d 2e 2e 2e 2f 2f 2f 2f 2f 00 00 00 то есть прекрасно видно, что значением 48 - 0x30 - и не пахнет! Сброс идёт мгновенно и после 0х2f сразу получается 0! Теперь понятно, почему была такая погрешность. К слову, весьма необычная особенность аппаратуры, первый раз сталкиваюсь с таким поведением  Цитата Так из картинок и текста все в общем-то понятно... А Вы говорите, что всё понятно в мануале. Вот если бы была диаграмма с растактовкой переполнения\сброса\установки (что встречается довольно часто), тогда действительно многих вопросов бы не возникало, и не приходилось бы прибегать к практическим исследованиям, с чём Вы сами соглашаетесь  Цитата(aaarrr @ Jul 4 2011, 16:37)  Если прерывания гарантированно укладываются в 65мс, то не нужно. Хм, да хоть прерывания будут длиться 650 миллисекунд - что изменится? Код считывания таймера такой: Код dword sys_counter() { dword hw, lw; do { hw = AT_TCB0->TCB_TC2.TC_CV; lw = AT_TCB0->TCB_TC1.TC_CV; } while (hw != AT_TCB0->TCB_TC2.TC_CV); return (hw << 16) | lw; } Переполнение 32 битного счётчика возможно за период равный 71 минуте. Всё, что меньше этого периода, внести ошибку не в состоянии, по моему...
|
|
|
|
|
Jul 5 2011, 06:31
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jul 5 2011, 01:46)  К слову, весьма необычная особенность аппаратуры, первый раз сталкиваюсь с таким поведением  А Вы говорите, что всё понятно в мануале. Вот если бы была диаграмма с растактовкой переполнения\сброса\установки (что встречается довольно часто), тогда действительно многих вопросов бы не возникало, и не приходилось бы прибегать к практическим исследованиям, с чём Вы сами соглашаетесь  Странно действительно, так как прямо противоречит описанию 36.5.6 Trigger  Посмотрю на досуге. Цитата(sonycman @ Jul 5 2011, 01:46)  Хм, да хоть прерывания будут длиться 650 миллисекунд - что изменится? Да, все правильно. С прерываниями я погорячился.
|
|
|
|
|
Jul 5 2011, 09:37
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Jul 5 2011, 13:14)  Надо будет сравнить с SAM7. Описания у них не отличаются. Впрочем, не припоминаю, чтобы мне приходилось использовать UP_RC с малым значением этого самого RC, а 0.01% мог и не заметить, конечно. Да я бы тоже не заметил, в других чипах (от AVR до C-M3 разных производителей) никогда не сверял получаемые клоки, так как не использую их для точных измерений. Только тут, раз уж взялся ковырять модуль и с наскоку заставить заработать как хотелось не удалось, стал проверять всё досконально... Однако в моём случае ошибка в 2% через всего лишь час дала погрешность, легко заметную на глаз  Процессор, кстати, нормально прожорливый - на 96 МГц кушает почти 60 миллиампер, из периферии включены только TC0-TC2 и PIOA-PIOB. Если включить всю остальную периферию (без её конфигурирования) - получается красивая циферка 100 ма
|
|
|
|
|
Jul 5 2011, 15:58
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Проверил на SAM7: таки да, не доходит до RC, что совсем не вяжется ни с описанием, ни с картинками  Такое ощущение, что таймер сбрасывается по сравнению асинхронно (что можно было бы предположить, глядя на картинку), однако точно известно, что SWTRG таймер без клока не сбрасывает, а на картинке эти источники объединены. Ну и в тексте явно написано, что для любого источника сброс срабатывает на следующем клоке. UPD: Поэкспериментировал еще с внешним клоком. В режиме WAVESEL_UP_AUTO сброс таймера происходит моментально по достижении им значения RC, т.е. первой ассемблерной командой даю последний фронт при CV = RC - 1, следующей считываю CV уже равным 0. Зато при установке дополнительно бита CPCSTOP таймер останавливается со значением CV = RC. SWTRIG честно срабатывает только на следующем фронте. То есть врут мануалы уже десять лет.
|
|
|
|
|
Jul 5 2011, 18:19
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Jul 5 2011, 22:10)  И с I2C, как Вы говорили, проблемы есть, и вроде седьмыми сэмами пользуется прорва народу - почему нет прогресса, интересно? Ваш вопрос уже содержит в себе ответ - потому что пользуется прорва народа. А если пользуются - значит все устраивает, и не нужно вкладывать силы и средства для кардинального улучшения продукции. Смертельных недостатков ведь нет, а остальное вполне можно пережить. Я вот пользуюсь отчасти по привычке, так как начинал с них тогда, когда никаких контроллеров у NXP, ST и прочих еще в помине не было. И далеко не всегда мой выбор бывает оправдан. Хотя есть огромное количество задач, где все равно какой контроллер поставить.
|
|
|
|
|
Aug 9 2011, 16:09
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Понятно, тогда устанавливаю их и забываю про это  Дальше вопрос по регистру таймаутов (HSMCI_DTOR) между двумя блоками данных. Максимальное значение таймаута получается равным (1048576 * 15) тактов мастер клока, который в моём случае равен 96 МГц. Получается 163 миллисекунды, тогда как по спецификации допускается пауза до 250 мс (при записи). Что-то не сходится. Может быть, мастер клок имеется ввиду MCCK (уже поделённый клок), а не MCK? ЗЫ: при инициализации SD карты ширина шины данных устанавливается как один бит. После инициализации надо бы включить четыре бита. Можно ли это делать "на лету", при включенном интерфейсе (но при этом никакого обмена данными нет)? Или необходимо отключать интерфейс битом MCIDIS?
|
|
|
|
|
Aug 9 2011, 16:57
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Aug 9 2011, 20:09)  Дальше вопрос по регистру таймаутов (HSMCI_DTOR) между двумя блоками данных.
Максимальное значение таймаута получается равным (1048576 * 15) тактов мастер клока, который в моём случае равен 96 МГц. Получается 163 миллисекунды, тогда как по спецификации допускается пауза до 250 мс (при записи).
Что-то не сходится. Может быть, мастер клок имеется ввиду MCCK (уже поделённый клок), а не MCK? А вот фиг их знает, что тут имелось в виду. У меня установлен максимум, а на деле таймауты отрабатывает софт. Цитата(sonycman @ Aug 9 2011, 20:09)  ЗЫ: при инициализации SD карты ширина шины данных устанавливается как один бит. После инициализации надо бы включить четыре бита. Можно ли это делать "на лету", при включенном интерфейсе (но при этом никакого обмена данными нет)?
Или необходимо отключать интерфейс битом MCIDIS? Я запрещал, а вот есть ли в этом необходимость - не помню
|
|
|
|
|
Aug 9 2011, 17:02
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Aug 9 2011, 20:57)  А вот фиг их знает, что тут имелось в виду. У меня установлен максимум, а на деле таймауты отрабатывает софт. Я запрещал, а вот есть ли в этом необходимость - не помню  Понятно, спасибо! Млин, во всех этих упрощённых спецификациях нет растактовки, бит MAXLAT: Max Latency for Command to Response, наверное, тоже стоит установить в макс. значение - 64 такта? ЗЫ: ага, вроде нашёл - 5 тактов для ACMD41, в остальных случаях - 64  Перед началом инициализации спецификация требует выдать 74 такта на карту. Это может обеспечить поле SPCMD регистра HSMCI_CMDR, равное 1. То есть выдать команду CMD0 с единичкой в SPCMD, получим 74 такта, а затем CMD0?
|
|
|
|
|
Aug 9 2011, 17:30
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Aug 9 2011, 21:02)  ЗЫ: ага, вроде нашёл - 5 тактов для ACMD41, в остальных случаях - 64  И CMD2. Цитата(sonycman @ Aug 9 2011, 21:02)  То есть выдать команду CMD0 с единичкой в SPCMD, получим 74 такта, а затем CMD0? Да, только у меня поле команды содержит все "1". Опять-таки не помню, принципиально ли это, или сделано просто для отделение кода инициализации от кодов других команд.
|
|
|
|
|
Aug 11 2011, 16:55
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Aug 10 2011, 00:40)  Я вводил поддержку SD за пару дней в страшной спешке, поэтому многих моментов не помню, к сожалению. А документацию, думаю, Вы сами успели оценить по достоинству. За пару дней - это мощно, конечно В доке мне больше всего не нравятся грубые ошибки типа капи-пэйст где попало и откровенное враньё во многих местах - чего стоят только 9 таймеров  В точной технической документации такого быть не должно. Ну да ладно, с Вашей помощью дело потихоньку идёт, спасибо! Как то странно организован регистр статуса HSMCI_SR - многие биты ошибок сбрасываются после чтения этого регистра. А если я жду завершения операции поллингом другого бита? К примеру, жду завершения мультисекторного чтения поллингом XFRDONE, а в это время может выставиться DCRCE: Data CRC Error, который я тогда благополучно проморгаю... Мне что, после каждого чтения регистра статуса выдёргивать и сохранять биты ошибок? В конечном итоге всё будет работать через DMA и прерывания, конечно, но осадочек остался...
|
|
|
|
|
Aug 11 2011, 18:02
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Aug 11 2011, 20:55)  За пару дней - это мощно, конечно  Дык, сроки такие были. Теперь имею, прямо скажем, не самый лучший код, который лень причесывать. Цитата(sonycman @ Aug 11 2011, 20:55)  Как то странно организован регистр статуса HSMCI_SR - многие биты ошибок сбрасываются после чтения этого регистра. А если я жду завершения операции поллингом другого бита? К примеру, жду завершения мультисекторного чтения поллингом XFRDONE, а в это время может выставиться DCRCE: Data CRC Error, который я тогда благополучно проморгаю... Мне что, после каждого чтения регистра статуса выдёргивать и сохранять биты ошибок? Что сбрасываются - это ничего, все-таки поллинг не есть гуд. А вот то, что поведение некоторых битов сего регистра из документации совсем не очевидно - это действительно плохо.
|
|
|
|
|
Aug 11 2011, 18:26
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Aug 11 2011, 22:02)  Что сбрасываются - это ничего, все-таки поллинг не есть гуд. А вот то, что поведение некоторых битов сего регистра из документации совсем не очевидно - это действительно плохо. А например? Какие подозрительно себя ведут? Посмотрел осциллографом на MCCK - он идёт на карту постоянно, то есть не гейтится вообще, активируется сразу после включения MCI. Хм, смысл тогда выдавать команду с 74 тактами? Достаточно просто подождать немножко  Попробовать включить Power Save Mode?
|
|
|
|
|
Aug 11 2011, 19:49
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Aug 11 2011, 22:26)  А например? Какие подозрительно себя ведут? Ну, например, очень интересно было бы узнать расположение событий BLKE, DTIP и DCRCE во времени. Тот же DTOE тоже интересен. Да что тут говорить, если большинство битов регистра SR упоминаются лишь в паре строчек его описания? Цитата(sonycman @ Aug 11 2011, 22:26)  Посмотрел осциллографом на MCCK - он идёт на карту постоянно, то есть не гейтится вообще, активируется сразу после включения MCI. Хм, смысл тогда выдавать команду с 74 тактами? Достаточно просто подождать немножко  Можно и подождать, но выдать команду просто удобнее.
|
|
|
|
|
Aug 21 2011, 18:34
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Что-то не пойму, почему у меня виснет контроллер после приблизительно недели работы батарейного блока от батареи.
Ситуация такая - имеется плата от стартеркита SK-MATSAM3U4, к ней я подпаял батарею CR2032 через стандартную схему с двумя диодами, запитав таким образом блок RTC от батареи при отключении питания (перемычку J7 снял).
Устанавливаю правильное время в регистр времени (регистр даты не трогаю) и отключаю питание. Хочу таким образом увидеть, насколько велика будет погрешность часов с течением времени.
В таком виде плата работает около недели нормально - время от времени подаю питание и смотрю, сколько натикало в RTC.
Включаю на след. день - контроллер не реагирует вообще ни на что! Программа не выполняется, даже J-Link подключится не может, сыпет ошибками. При этом потребление тока контроллером идёт на полную - около 70 ма. Напряжение на батарее при этом 3050 мв.
Всё начинает нормально функционировать только после сброса по RSTB, то есть флеш не слетает, а происходит какое-то залочивание контроллера при включении... Плата лежит дома, при комнатной температуре...
Непонятно это всё, это что-же, мне теперь каждую неделю батарейку передёргивать и переустанавливать часы? Мог ли я что-то напортачить в коде стартапа? Но эта проблема возникает только после простоя платы без питания несколько дней...
|
|
|
|
|
Aug 25 2011, 21:29
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(aaarrr @ Jul 5 2011, 19:58)  Проверил на SAM7: таки да, не доходит до RC, что совсем не вяжется ни с описанием, ни с картинками  Такое ощущение, что таймер сбрасывается по сравнению асинхронно (что можно было бы предположить, глядя на картинку), однако точно известно, что SWTRG таймер без клока не сбрасывает, а на картинке эти источники объединены. Ну и в тексте явно написано, что для любого источника сброс срабатывает на следующем клоке. UPD: Поэкспериментировал еще с внешним клоком. В режиме WAVESEL_UP_AUTO сброс таймера происходит моментально по достижении им значения RC, т.е. первой ассемблерной командой даю последний фронт при CV = RC - 1, следующей считываю CV уже равным 0. Зато при установке дополнительно бита CPCSTOP таймер останавливается со значением CV = RC. SWTRIG честно срабатывает только на следующем фронте. То есть врут мануалы уже десять лет. я года 4 сидел с "неправильным" тактом из-за этой "особенности", правда в моем случае ошибка была практически ничтожна 1/24000, но все же я ее случайно поймал и после пятого прочтения даташита я нашел нужные слова: When WAVSEL = 10, the value of TC_CV is incremented from 0 to the value of RC, then automaticallyreset on a RC Compare. автоматически это видимо именно значит в тот же момент не зависимо от прескейлера и выяснилось это все при программировании PWM контроллера когда у меня банально не совпали частоты... ну и да, я включился в ряды SAM3водил, так что по мере освоения могу тоже давать ответы и задавать вопросы, и если топикстартер не против(?) то буду делать это в этой теме...
|
|
|
|
|
Aug 30 2011, 12:12
|
Группа: Участник
Сообщений: 11
Регистрация: 25-05-11
Пользователь №: 65 261

|
Здравствуйте, у меня появилась проблема при работе с внешней NAND Flash. При подаче команды Read ID к Flash, сигнал CE формируется неправильно (не становится в актиный уровень). Вследствии этого флэш не реагирует на команду, в чем может быть проблема ?
|
|
|
|
|
Aug 31 2011, 12:13
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Aug 21 2011, 22:34)  Всё начинает нормально функционировать только после сброса по RSTB, то есть флеш не слетает, а происходит какое-то залочивание контроллера при включении... Плата лежит дома, при комнатной температуре...
Непонятно это всё, это что-же, мне теперь каждую неделю батарейку передёргивать и переустанавливать часы? Мог ли я что-то напортачить в коде стартапа? Но эта проблема возникает только после простоя платы без питания несколько дней... Наблюдал точно такое же поведение "родного" кита от атмела. От батарейки в своем устройстве в результате был вынужден отказаться. Кстати, на вашей плате стоит -ES, или более свежий кристалл? Цитата(sonycman @ Aug 26 2011, 17:27)  Только вот запропастился куда-то наш гуру, в отпуске, наверное  Вроде того. Цитата(BurglarInt @ Aug 30 2011, 16:12)  Здравствуйте, у меня появилась проблема при работе с внешней NAND Flash. При подаче команды Read ID к Flash, сигнал CE формируется неправильно (не становится в актиный уровень). Вследствии этого флэш не реагирует на команду, в чем может быть проблема ? В ревизии -ES один из CE не работает - не ваш ли случай?
|
|
|
|
|
Aug 31 2011, 21:08
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Aug 31 2011, 16:13)  Наблюдал точно такое же поведение "родного" кита от атмела. От батарейки в своем устройстве в результате был вынужден отказаться. Кстати, на вашей плате стоит -ES, или более свежий кристалл? У меня ревизия А. Возможно, залочивание кристалла происходит по причине слишком медленного нарастания напряжения питания. Проблема возникает при запитывании от лабораторного источника с ограничением макс. тока на уровне 250 ма (пробовал и 750 - всё одно). Последние 10 дней запитываю от USB порта компьютера - пока ни разу не повис. Потом попробую установить ограничение тока лабораторника на несколько ампер, для эксперимента. ЗЫ: вот уже несколько лет пользуюсь лабораторником - проблем с нарастанием напряжения и зависанием не было никогда. SAM3U первый проблемный кристалл. И проблема возникает только при питании батарейного блока от батареи. Наверное, тоже придётся отказаться от встроенного RTC
|
|
|
|
|
Sep 12 2011, 22:03
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(singlskv @ Aug 26 2011, 01:29)  то буду делать это в этой теме... Ну вот и вопросики нарисовались: 1. Ремап векторов в SRAM улучшает производительность(учитываем различные шины для доступа к FLASH и SRAM) ? 2. Размещение функции которая должна максимально быстро работать в SRAM дает преимущество как на ARM7 или нет ? (ARM вроде как утверждает что из-за наличия многих шин код не нужно размещать в SRAM) 3. Какие ограничения имеет PDC по пропускной способности ?
|
|
|
|
|
Sep 12 2011, 22:27
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(aaarrr @ Sep 13 2011, 02:12)  1-2. Нет. А что делать с функциями записи в флеш ? у меня что-то какая-то фигня беру свою стандартную(от арм7) функцию которая работает в секции .fast и считает просто CRC16 вылетаю в hardfault соответственно вопрос про запись в флеш запускать из SRAM(а как ?) или юзать IAP из SAM-BA ? хотя конечно возможно у CrossWorks странный конфиг по умолчанию....
|
|
|
|
|
Sep 12 2011, 22:32
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(singlskv @ Sep 13 2011, 02:27)  А что делать с функциями записи в флеш ? Как и раньше - писать из RAM или другого банка. Цитата(singlskv @ Sep 13 2011, 02:27)  хотя конечно возможно у CrossWorks странный конфиг по умолчанию.... Посмотрите map.
|
|
|
|
|
Sep 12 2011, 22:39
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(aaarrr @ Sep 13 2011, 02:32)  Как и раньше - писать из RAM или другого банка Посмотрите map. то есть у Вас из рам все работает ? при записи в флеш тогда буду копать скрипт линкера... просто у меня какая-то фигня генерица компилятором похоже... не вижу чего-нить непрвильного в map файле Hardfault генерит вызов функции WORD ModbusCrcBuff(BYTE *buff, DWORD len); вот их описание: CODE //---- CRC sections #define FAST_SECTION __attribute__((section(".fast"))) #define FLASH_CONST_ARRAY static const #define RAM_ARRAY
#define MODBUS_CRC_SECTION FAST_SECTION #define CRC8_SECTION FAST_SECTION #define MODBUS_CRC_TABLE RAM_ARRAY #define CRC8_TABLE RAM_ARRAY .........................
#if !defined(MODBUS_CRC_SECTION) #define MODBUS_CRC_SECTION #endif
#if !defined(CRC8_SECTION) #define CRC8_SECTION #endif
#if !defined(FLASH_CONST_ARRAY) #define FLASH_CONST_ARRAY static const #endif
#if !defined(MODBUS_CRC_TABLE) #define MODBUS_CRC_TABLE FLASH_CONST_ARRAY #endif
#if !defined(CRC8_TABLE) #define CRC8_TABLE FLASH_CONST_ARRAY #endif
#include "ModbusCrc.h" MODBUS_CRC_TABLE BYTE ModbusCrcLo[256] = { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 };
MODBUS_CRC_TABLE BYTE ModbusCrcHi[256]= { 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10,
0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0,
0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 };
WORD ModbusCrc(WORD crc, BYTE data) MODBUS_CRC_SECTION; WORD ModbusCrc(WORD crc, BYTE data) { BYTE crclo = crc; BYTE crchi = crc >> 8; BYTE index = crclo ^ data; crclo = crchi ^ ModbusCrcLo[index]; crchi = ModbusCrcHi[index]; return (crchi << 8) | crclo; }
WORD ModbusCrcBuff(BYTE *buff, DWORD len) MODBUS_CRC_SECTION; WORD ModbusCrcBuff(BYTE *buff, DWORD len) { BYTE index; BYTE crclo = MODBUS_CRC_LO_DEFAULT; BYTE crchi = MODBUS_CRC_HI_DEFAULT; while (len--) { index = crclo ^ *buff++; crclo = crchi ^ ModbusCrcLo[index]; crchi = ModbusCrcHi[index]; }
return (crchi << 8) | crclo; }
CRC8_TABLE BYTE DallasCrc[256] = { // Полином 0x8C 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 };
BYTE Crc8Buff(BYTE *buff, DWORD len) CRC8_SECTION; BYTE Crc8Buff(BYTE *buff, DWORD len) { BYTE index; BYTE crc = CRC8_DEFAULT; while (len--) { index = crc ^ *buff++; crc = DallasCrc[index]; }
return crc; }
|
|
|
|
|
Sep 12 2011, 22:51
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(singlskv @ Sep 13 2011, 02:39)  то есть у Вас из рам все работает ? при записи в флеш Не пробовал, но нет оснований не доверять документации в данном вопросе. Цитата(singlskv @ Sep 13 2011, 02:39)  тогда буду копать скрипт линкера... просто у меня какая-то фигня генерица компилятором похоже... Вообще, я бы IAP-функцию использовал, наверное - меньше телодвижений и расхода RAM нет.
|
|
|
|
|
Sep 12 2011, 23:22
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(aaarrr @ Sep 13 2011, 02:51)  ообще, я бы IAP-функцию использовал, наверное - меньше телодвижений и расхода RAM нет. В конечном продукте наверное использую IAP но понять что я делаю не так при размещении функций в SRAM хотелось-бы... может я еще что-нить недопонял в настройке басматрикск ? у меня пока вот такЖ Код ldr r1, =MATRIX_BASE_ADDRESS ldr r0, =(2 << MATRIX_SCFG0_DEFMSTR_TYPE_BIT) | (1 << MATRIX_SCFG0_FIXED_DEFMSTR_BIT) str r0, [r1, #MATRIX_SCFG0_BASE_OFFSET] str r0, [r1, #MATRIX_SCFG1_BASE_OFFSET] ldr r0, =(2 << MATRIX_SCFG0_DEFMSTR_TYPE_BIT) | (0 << MATRIX_SCFG0_FIXED_DEFMSTR_BIT) str r0, [r1, #MATRIX_SCFG3_BASE_OFFSET] str r0, [r1, #MATRIX_SCFG4_BASE_OFFSET]
|
|
|
|
|
Sep 22 2011, 18:22
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Потихоньку пишу инициализацию карты памяти контроллером HSMCI. Дошёл до команды ACMD41, после выдачи которой необходимо ждать, пока не снимется статус BUSY. В мануале это делается опросом флага NOTBUSY регистра статуса, пока он не установится в 1. Но проблема в том, что этот флаг находится в 1 сразу после завершения команды  То есть как только устанавливается CMDRDY, опрашиваю NOTBUSY - он всегда в единичке. Соответственно инициализация карты не завершается, в ответе команды ACMD41 (регистр OCR карты памяти) биты 31 и 30 сброшены... Если подождать около секунды и повторно выдать ACMD41 - то в ответе уже всё ОК - бит 31 установлен (инициализация завершена) и 30 сообщает правильную информацию, является ли карта SDHC или нет. Спрашивается - почему контроллер HSMCI не выполняет ожидание статуса BUSY? Может быть, я что-то делаю не так?
|
|
|
|
|
Sep 23 2011, 16:52
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Sep 23 2011, 20:29)  Инициализация карты у меня получается такая: PowerOn -> CMD0 -> CMD8 -> ACMD41 -> CMD2 -> CMD3 -> CMD9 -> CMD7 -> ACMD6. А у меня такая: PowerOn -> CMD0 -> CMD8 -> ACMD41 -> CMD2 -> CMD3 -> CMD7 (select) -> ACMD51 -> ACMD6 (только если поддерживается 4 бита) -> Проверка и выбор high speed (CMD6), если версия спецификации >= 2 -> CMD7 (deselect) -> CMD9 -> Установка скорости интерфейса Цитата(sonycman @ Sep 23 2011, 20:29)  Хотел ещё спросить по поводу операций с блоками - в поле Transfer Type (TRTYP) регистра комманд HSMCI_CMDR какие нужно выбирать значения для single и multiple блоков? Вроде как 0 для одно- и 1 для много- секторных чтения\записи, но вот смущает ещё значение 5 - SDIO Block...  SDIO и SD Memory - это совсем разные вещи.
|
|
|
|
|
Sep 23 2011, 17:00
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Спасибо! Цитата(aaarrr @ Sep 23 2011, 20:52)  если версия спецификации >= 2 -> CMD7 (deselect) -> CMD9 -> Установка скорости интерфейса А вот тут можно разъяснить, для чего делать deselect? Ведь CMD9 можно выдать вообще до CMD7 (select)? Или это имеет отношение к CMD6? Цитата SDIO и SD Memory - это совсем разные вещи. Вот оно что, а у меня эти понятия перемешались вместе  Цитата только если поддерживается 4 бита - неужели встречаются карточки без поддержки 4 бит?
|
|
|
|
|
Sep 23 2011, 17:22
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Sep 23 2011, 21:00)  А вот тут можно разъяснить, для чего делать deselect? Ведь CMD9 можно выдать вообще до CMD7 (select)? Или это имеет отношение к CMD6? CMD9 можно выдать только карте в "stby", а ACMD51 - только в "tran", поэтому сначала карта выбирается через CMD7 (select), затем переводится в "stby" через CMD7 (deselect). Можно сделать так: PowerOn -> CMD0 -> CMD8 -> ACMD41 -> CMD2 -> CMD3 -> CMD9 -> CMD7 (select) -> ACMD51 -> ACMD6 (только если поддерживается 4 бита) -> Проверка и выбор high speed (CMD6), если версия спецификации >= 2 -> Установка скорости интерфейсаНаврал, нельзя. Цитата(sonycman @ Sep 23 2011, 21:00)  - неужели встречаются карточки без поддержки 4 бит? Ну, как бы надо проверять, если уж все делать честно. Не встречал до сих пор
|
|
|
|
|
Dec 15 2011, 10:28
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Хм, этот HSMCI вообще может корректно обрабатывать статус BUSY карты памяти? Подаю команду CMD7 подряд два раза - просто для интереса, чтобы посмотреть, как меняется статус карточки. Первый раз она обрабатывается нормально, но во второй получаю ошибку таймаута ответа (RTOE: Response Time-out Error)...  Вероятно, карточка всё ещё находится в состоянии BUSY после первой команды CMD7, и этот статус опять не обрабатывается контроллером Но почему? Ведь тип ответа команды задаю правильно - R1b? Разве это не означает, что контроллер должен автоматически ожидать, пока карта не снимет BUSY?
|
|
|
|
|
Dec 15 2011, 10:43
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 15 2011, 14:40)  Нет. Это означает, что программа должна дождаться флага NOTBUSY в SR. Поставил ожидание: Код do { status = AT_MCI0->MCI_SR; } while (!(status & AT_MCI_NOTBUSY)); но никакого эффекта...  Что делать - то? Похоже, повторяется ситуация, как с командой ACMD41 - флаг NOTBUSY устанавливается мгновенно с CMDRDY... ЗЫ: если ждать нужно ручками - зачем тогда вообще ввели специальный тип команды с ответом R1b? Толку то нет. ЗЗЫ: а, так тут наверное я сам напортачил - подавать CMD7(SELECT) два раза подряд, наверное, нельзя. Вот карточка и входит в ступор... Сейчас попробую сначала CMD7(SELECT), а потом сразу CMD7(DESELECT)...
|
|
|
|
|
Dec 15 2011, 10:55
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 15 2011, 14:43)  но никакого эффекта...  Что делать - то? Странно, проверка NOTBUSY у меня вполне себе работает. Цитата(sonycman @ Dec 15 2011, 14:43)  Похоже, повторяется ситуация, как с командой ACMD41 - флаг NOTBUSY устанавливается мгновенно с CMDRDY... ACMD41 - это особый случай, и там совсем другой "busy". Кстати, взвода CMDRDY перед проверкой NOTBUSY дожидаетесь? Цитата(sonycman @ Dec 15 2011, 14:43)  ЗЫ: если ждать нужно ручками - зачем тогда вообще ввели специальный тип команды с ответом R1b? Толку то нет. Потому что в противном случае контроллер возможно даже смотреть не будет busy status.
|
|
|
|
|
Dec 15 2011, 11:00
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 15 2011, 14:55)  Кстати, взвода CMDRDY перед проверкой NOTBUSY дожидаетесь? Конечно, такая же проверка: Код AT_MCI0->MCI_CMDR = comm_reg; do { status = AT_MCI0->MCI_SR; } while (!(status & AT_MCI_CMDRDY)); Попробовал и так: сначала CMD7(SELECT), а потом сразу CMD7(DESELECT). Без разницы - получаю RTOE...
|
|
|
|
|
Dec 15 2011, 11:19
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 15 2011, 15:14)  Ну, на CMD7(DESELECT) ответа и не должно быть.
Сдается мне, все правильно: повторная передача CMD7 переводит карту назад в stand-by, ответа и не должно быть. Да, спасибо, сейчас попробую отправить вслед за CMD7 другую команду. Действительно, с CMD7 всё не так просто - судя по спецификации на эту команду карта отвечает только при переходе с STBY на TRAN. ЗЫ: отправил следом ACMD51 - всё в порядке, ошибок нет  Впрочем, ошибок нет, даже если совсем убрать ожидание NOTBUSY. То ли это из-за низкой скорости интерфейса (работает пока на паре мегагерц, в отладочных соображениях), и карта успевает отпустить линию данных, то ли всё же контроллер отслеживает статус автоматически...
|
|
|
|
|
Dec 15 2011, 15:05
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Ну вот, вроде сделал чтение сектора, теперь надо бы DMA подключать. В даташите на этот счёт всё довольно мутно - какие-то дескрипторы, выравнивание по WORD и прочие грустные штуки  Мне бы организовать чтение\запись по произвольному адресу в памяти и с произвольным кол-вом секторов. Может ли DMAC выполнять чтение\запись памяти по произвольному адресу, а не только по выровненному до слова? Вроде бы есть поля в регистрах, этому сопутствующие. С дескрипторами так и не пойму, допустим, надо мне прочесть с карты памяти 32 сектора последовательно в память, неужели для этого придётся создавать в памяти 32 дескриптора? Можно ли обойтись одним так, чтобы чтение 32 секторов выполнялось за один раз, или придётся 32 раза перепрограммировать DMA (на каждый сектор)? Судя по описанию в даташите, придётся возиться с каждым сектором
|
|
|
|
|
Dec 15 2011, 16:15
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 15 2011, 15:19)  Впрочем, ошибок нет, даже если совсем убрать ожидание NOTBUSY. То ли это из-за низкой скорости интерфейса (работает пока на паре мегагерц, в отладочных соображениях), и карта успевает отпустить линию данных, то ли всё же контроллер отслеживает статус автоматически... Ну, на CMD7 карте задумываться особо и не о чем. Цитата(sonycman @ Dec 15 2011, 19:05)  Может ли DMAC выполнять чтение\запись памяти по произвольному адресу, а не только по выровненному до слова? Может, но тогда ширина передачи должна быть снижена до байта, что скажется на производительности - 3/4 возможности шины будут пущены на ветер. Цитата(sonycman @ Dec 15 2011, 19:05)  Можно ли обойтись одним так, чтобы чтение 32 секторов выполнялось за один раз, или придётся 32 раза перепрограммировать DMA (на каждый сектор)? Теоретически можно обойтись одним. Контроллеру HSMCI в общем-то все равно, как запрограммирован контроллер DMA, лишь бы данные шли.
|
|
|
|
|
Dec 15 2011, 18:59
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 15 2011, 20:15)  Может, но тогда ширина передачи должна быть снижена до байта, что скажется на производительности - 3/4 возможности шины будут пущены на ветер. Понятно. Но зато не надо париться с выравниванием. Что-то я слабо представляю, как вообще возможно всегда получать выровненный адрес в памяти, с которой будет работать файловая система в реальном приложении. Хотя, среди примеров есть способ программирования DMA несколькими дескрипторами для передачи блока данных длиной не кратной 4. Если только делать что-то похожее... Среди регистров DMAC есть поля Source Chunk Transfer Size и Destination Chunk Transfer size. Могут принимать значения 1 или 4. Это что-то типа пакетной передачи? Последнее, как я понимаю, будет лучше? Цитата(aaarrr @ Dec 15 2011, 20:15)  Теоретически можно обойтись одним. Контроллеру HSMCI в общем-то все равно, как запрограммирован контроллер DMA, лишь бы данные шли. В общем, буду пробовать
|
|
|
|
|
Dec 15 2011, 19:10
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 15 2011, 22:59)  Что-то я слабо представляю, как вообще возможно всегда получать выровненный адрес в памяти, с которой будет работать файловая система в реальном приложении. А в чем проблема? Файловой системе все равно придется работать с целыми секторами, так почему бы их не выровнять по границе слова? Кроме того, не стоит забывать, что ядру тоже не всегда удобно работать с не выровненными адресами - всякие memset/memcpy это замедлит. Цитата(sonycman @ Dec 15 2011, 22:59)  Среди регистров DMAC есть поля Source Chunk Transfer Size и Destination Chunk Transfer size. Могут принимать значения 1 или 4. Это что-то типа пакетной передачи?
Последнее, как я понимаю, будет лучше? Да, это значит, что HSMCI и DMA будут между собой обмениваться блоками по 4 слова, что, несомненно, лучше. Только не забудьте установить это поле и у HSMCI и у DMAC одинаково.
|
|
|
|
|
Dec 15 2011, 19:22
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 15 2011, 20:15)  Теоретически можно обойтись одним. Контроллеру HSMCI в общем-то все равно, как запрограммирован контроллер DMA, лишь бы данные шли. Но в чём проблема - в примерах для READ_SINGLE_BLOCK в качестве источника данных всегда указывается не регистр HSMCI_RDR, а так называемая "апертура" FIFOx Memory Aperture, при этом указатель на неё задаётся как инкрементируемый. Это FIFO имеет граничный размер (HSMCI_FIFOx[x=0..255]), и при чтении\записи больших блоков не приведёт ли это к выходу за пределы этой памяти? Цитата(aaarrr @ Dec 15 2011, 23:10)  А в чем проблема? Файловой системе все равно придется работать с целыми секторами, так почему бы их не выровнять по границе слова? Кроме того, не стоит забывать, что ядру тоже не всегда удобно работать с не выровненными адресами - всякие memset/memcpy это замедлит. Ну, к примеру, если я захочу записать пару килобайт данных, пусть даже выровненных в памяти, в файл с произвольным смещением от его начала (не нулевым), то это будет как работать? Сначала в буфер файловой системы считается первый сектор, в который частично попадают эти данные, в него копируется их кусок, затем этот сектор записывается. Далее уже идёт прямая запись в сектора из памяти с абсолютно произвольного по выравниванию места, которое будет зависеть от начального смещения по файлу...
|
|
|
|
|
Dec 15 2011, 20:30
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 15 2011, 23:22)  Но в чём проблема - в примерах для READ_SINGLE_BLOCK в качестве источника данных всегда указывается не регистр HSMCI_RDR, а так называемая "апертура" FIFOx Memory Aperture, при этом указатель на неё задаётся как инкрементируемый. Упс. Да, забыл это обстоятельство. Тогда остается делать цепочку дескрипторов DMA. Впрочем, цепочку не обязательно - прерывания все равно будут, а перепрограммировать DMA - секундное дело. Цитата(sonycman @ Dec 15 2011, 23:22)  Далее уже идёт прямая запись в сектора из памяти с абсолютно произвольного по выравниванию места, которое будет зависеть от начального смещения по файлу... Идея понятна, да. У меня просто между файловой системой и картой проложен еще один уровень из дискового кэша и буфера записи, поэтому вопросов с выравниванием нет. Тогда остается извернуться через поле OFFSET регистра HSMCI_DMA, но он, как я понимаю, действителен только для записи.
|
|
|
|
|
Dec 16 2011, 01:41
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 16 2011, 00:30)  Упс. Да, забыл это обстоятельство. Тогда остается делать цепочку дескрипторов DMA. Впрочем, цепочку не обязательно - прерывания все равно будут, а перепрограммировать DMA - секундное дело. Эх, вот если бы не было никакой "апертуры", а был бы регистр типа HCMI_RDR безо всякой инкрементации... Почему так сделано, интересно? Цитата Идея понятна, да. У меня просто между файловой системой и картой проложен еще один уровень из дискового кэша и буфера записи, поэтому вопросов с выравниванием нет. Тогда остается извернуться через поле OFFSET регистра HSMCI_DMA, но он, как я понимаю, действителен только для записи. Я так и понял, у Вас куча памяти, и идёт копирование данных сначала в выровненную память\кеш, а уже потом на карточку... Да, непонятно с этим офсетом. Думаю, тут можно поступить тоже используя дескрипторы - к примеру, понадобится три штуки для выравнивания сектора из 512 байт: 1. (MEMORY_ADDRESS & 0x03) - получаем 1 - 3 байта, для которых создаём дескриптор с BYTE доступом. 2. дескриптор с WORD доступом, обрабатывающий основную часть данных. 3. последний дескриптор BYTE, перебрасывающий последние 1-3 байта. Чтобы уменьшить частоту прерываний, выделю память для 3-4 дескрипторов. С другой стороны, возможно не стоит париться и сделать всё на BYTE дескрипторах, знать бы ещё, насколько загружена получается внутренняя шина...
|
|
|
|
|
Dec 16 2011, 02:08
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 16 2011, 05:41)  Почему так сделано, интересно? Надо полагать, для ускорения всего и вся  Вполне возможно, что этому процессору оно и не нужно, но ведь IP-блоки тоже подвержены copy-paste. Цитата(sonycman @ Dec 16 2011, 05:41)  Я так и понял, у Вас куча памяти, и идёт копирование данных сначала в выровненную память\кеш, а уже потом на карточку... Именно так. Цитата(sonycman @ Dec 16 2011, 05:41)  Думаю, тут можно поступить тоже используя дескрипторы - к примеру, понадобится три штуки для выравнивания сектора из 512 байт: 1. (MEMORY_ADDRESS & 0x03) - получаем 1 - 3 байта, для которых создаём дескриптор с BYTE доступом. Так нельзя: контроллер HSMCI ждет на входе 32 бита и никак иначе. Не получится ему три байта скормить, кроме как через OFFSET, который и указывает, сколько байт нужно проигнорировать. А вот с чтением, похоже, остается только байтовый доступ.
|
|
|
|
|
Dec 16 2011, 06:46
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 16 2011, 06:08)  Так нельзя: контроллер HSMCI ждет на входе 32 бита и никак иначе. Не получится ему три байта скормить, кроме как через OFFSET, который и указывает, сколько байт нужно проигнорировать. А вот с чтением, похоже, остается только байтовый доступ. Да, с записью, оказывается, все много проще, задать offset и дело в шляпе  Странно, что для чтения не предусмотрели такую фичу вместо сомнительного ROPT... Интересно, а как себя поведет DMA при возникновении ошибки, к примеру, при чтении, если карта не отдаст количество данных, на которые он запрограммирован? Повиснет?
|
|
|
|
|
Dec 16 2011, 20:47
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 16 2011, 10:46)  Интересно, а как себя поведет DMA при возникновении ошибки, к примеру, при чтении, если карта не отдаст количество данных, на которые он запрограммирован? Повиснет? Карта не отдать просто не сможет: хост подает клок и снимает данные вне зависимости от того, что думает карта. Другое дело, что в таком случае появится ошибка CRC, но DMA об этом и не узнает.
|
|
|
|
|
Dec 17 2011, 01:39
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aaarrr @ Dec 17 2011, 00:47)  Карта не отдать просто не сможет: хост подает клок и снимает данные вне зависимости от того, что думает карта. Другое дело, что в таком случае появится ошибка CRC, но DMA об этом и не узнает. Ну как же - есть же Start Bit, есть специальные токены начала данных (по крайней мере в режиме SPI были), то есть хост может определить момент появления данных. К примеру, если после команд чтения данных не ждать установки флага NOTBUSY и сразу попытаться подавать следующую команду - получаем зависон на циклическом опросе флага AT_MCI_RXRDY, который никогда уже не установится - карточка-то молчит. Или просто попробовать прочитать больше данных, чем карта отдаёт - скажем, вместо 8 байт команды ACMD51 попытаться прочесть 9 - аналогичный зависон... То есть хост определяет, отдаёт карта данные, или нет с точностью до байта. Но это касается работы без DMA, с ним, возможно, будет несколько иначе... PS: хотя бог знает, может просто я чего нибудь напутал...
|
|
|
|
|
Dec 19 2011, 08:12
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 17 2011, 05:39)  То есть хост определяет, отдаёт карта данные, или нет с точностью до байта. Тут некоторая путаница в понятиях получается. Чисто гипотетически предположим, что хост считывает 16 байт, а на деле карта возвращает 8. В этом случае будут нормально приняты старт, первые 8 байт, а вместо остальных будут приняты 0xff, что повлечет ошибку CRC. Понятно, что хост не знает, сколько на самом деле было передано картой. Цитата(sonycman @ Dec 17 2011, 05:39)  Но это касается работы без DMA, с ним, возможно, будет несколько иначе... С DMA все просто - он знать ничего не знает об ошибках той периферии, которую обслуживает. То есть его придется при ошибках переконфигурировать полностью вручную.
|
|
|
|
|
Dec 20 2011, 10:30
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Эмм... дошёл до конфигурирования DMA применительно к HSMCI. Поставил в тупик регистр DMAC_CFGx, конкретно - его поля DST_PER и SRC_PER. Где искать эти идентификаторы? Как понимаю, нужны ID для HSMCI и для MEMORY. Нашёл только табличку с ID на 43 странице мануала, но это по ходу не то  ... А, все, нашел, в другом разделе было  И имеет ли смысл что-то записывать в поле AHB_PROT? Так и не понял, для чего оно и чем отличаются его значения.
|
|
|
|
|
Dec 20 2011, 13:34
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sonycman @ Dec 20 2011, 14:30)  Нашёл только табличку с ID на 43 странице мануала, но это по ходу не то  ... Табличка есть на странице 28 (7.6 DMA Controller). Цитата(sonycman @ Dec 20 2011, 14:30)  И имеет ли смысл что-то записывать в поле AHB_PROT? Так и не понял, для чего оно и чем отличаются его значения. Ну, как минимум младший бит должен стоять, как я понимаю.
|
|
|
|
|
Dec 20 2011, 21:40
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
В мануале в примерах программирования DMA под HSMCI присутствуют поля регистров DMAC, такие, как: Цитата –DIF and SIF are set with their respective layer ID. If SIF is different from DIF, the DMA controller is able to prefetch data and write HSMCI simultaneously. Цитата –DST_REP is set to zero meaning that address are contiguous. Цитата Program LLI_W.DMAC_DSCRx with the address of LLI_B descriptor. And set DSCRx_IF to the AHB Layer ID. которые отсутствуют в описании самих регистров. Очередной copy\paste, на который стоит забить?
|
|
|
|
|
Dec 20 2011, 23:37
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Попробовал запрограммировать DMAC на чтение из HSMCI 512 байтового сектора с доступом BYTE для записи в не выравненный буфер: Код HDMA_CTRLA = AT_HDMA_SRC_WIDTH_BYTE | AT_HDMA_DST_WIDTH_BYTE | AT_HDMA_SCSIZE_1 | AT_HDMA_DCSIZE_1 | AT_HDMA_BTSIZE(512); Ничего не получилось В память записалась 1/4 часть данных (128 байт, вместо 512), всё вперемешку, флаги окончания передачи DMA не выставились. Видимо, читать из фифо побайтно оно не может, хватает сразу слово и получается мешанина... Получилось так: Код HDMA_CTRLA = AT_HDMA_SRC_WIDTH_WORD | AT_HDMA_DST_WIDTH_BYTE | AT_HDMA_SCSIZE_1 | AT_HDMA_DCSIZE_1 | AT_HDMA_BTSIZE(128); Целостность данных в порядке, всё ровненько, флаги окончания установлены
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|