Jump to content

    

501-й

Участник
  • Content Count

    37
  • Joined

  • Last visited

Community Reputation

0 Обычный

About 501-й

  • Rank
    Участник

Информация

  • Город
    Array
  1. Ну да, f1 не функция, а имя функции. Значением f1 является адрес функции. Две записи абсолютно одинаковы: void (*v1)(void) = f1; void (*v2)(void) = &f1; Для адреса функции оператор () выполняет вызов соответствующей функции. Т.е. вызов функции по известному адресу можно сделать так: (void (*)(int)) 0x1000 (5); Илья
  2. /* ct-assert.h */ /* макросы проверяют, что ex константа и не 0 */ #if !defined( CT_ASSERT_EXPR ) #define CT_ASSERT_EXPR(ex) ((struct { int assert:(ex) ? 1 : -1; } *)0 ? 0 : 0) #endif /* !defined( CT_ASSERT_EXPR ) */ #if !defined( CT_ASSERT_DECL ) #define CT_ASSERT_DECL(ex) extern char ct_assert_[ CT_ASSERT_EXPR(ex)+1 ] #endif /* !defined( CT_ASSERT_DECL ) */ #if !defined( CT_ASSERT ) #define CT_ASSERT(ex) (void)CT_ASSERT_EXPR(ex) #endif /* !defined( CT_ASSERT ) */ /* End of file ct-assert.h */ Используй макрос CT_ASSERT_EXPR(). Он всегда равен 0, если скомпилировался без ошибок. Илья
  3. RM0090 Reference manual, Doc ID 018909 Rev 6, p.1005/1710: SDIO_CK is the clock to the card: one bit is transferred on both command and data lines with each clock cycle. The clock frequency can vary between 0 MHz and 20 MHz (for a MultiMediaCard V3.31), between 0 and 48 MHz for a MultiMediaCard V4.0/4.2, or between 0 and 25 MHz (for an SD/SD I/O card). Так что 25 МГц -- это максимум для работы с SD карточкой. Кроме того, без DMA передача данных в SDIO будет прерываться на время обработки прерываний, что вызовет TXUNDERR. То, что у вас есть буфер на 200 мс -- это хорошо, но мало. Внимательно почитайте раздел 4.13 Speed Class Specification в документе SD Specifications Part 1 Physical Layer Simplified Specification; максимальное допустимое время обновления FAT для карточек -- 750 мс. Так что буфера менее чем на 800 мс может не хватить. При записи на карточку основное время уходит на ожидание готовности карточки. Сама передача занимает вряд ли более 10% времени (при записи по одному сектору). Так что увеличение частоты в 2 раза, если бы это можно было сделать, даст прирост не более 5%. Гораздо больший выигрыш даст правильное выравнивание данных в памяти (чтобы писать блоками по 4 или 8 кБ за раз) и на карточке и предварительная подготовка карточки. И еще про заполнение FIFO SDIO. При частоте 48 МГц (допустим, модуль будет работать) данные в FIFO нужно добавлять в среднем каждые 28 тактов (у вас же 4 линии данных?, ядро работает на частоте 168 МГц?). Функция SDIO_WriteData -- это не макрос! Вызов, возврат, считывание слова из памяти, запись в FIFO -- это всё запросто может длиться более 28 тактов. Так что без DMA вообще никак. Илья
  4. Приветствую! Модель SST хорошо работает до того момента, когда с одним и тем же ресурсом нужно работать из потоков с разным приоритетом. Реальный пример: на шине висят пультик и второй МК, связь с которым должна завершиться в течении 300 мкс (каждые 3 мс). Или объединять логику пультика (которая в разных проектах одна и та же) с логикой связи со вторым МК, или разносить по разным потокам с их синхронизацией. Во втором случае при добавлении абонента на шину первые два потока вообще менять не надо. А SST? Илья
  5. Человек не осознал сложность, поторопился. Этот вариант уже отвергли. Не менее 5 тактов (я бы рассчитывал на значение более 7, но если нужно точно, то это можно проверить). Плюс задержки из-за конфликтов во время доступа ядра и DMA к шине данных (в SPI, USART и т.п. эти задержки сглаживаются наличием промежуточного буфера). Илья
  6. Да. 'LD reg, Z+' 2 такта. Так что три такта -- минимум. Синхронизацию можно глянуть на avrfreaks.net. Там есть проект вывода видеосигнала из икс-меги, и в нем есть синхронизация сигналов до такта. И я там же код для синхронизации приводил. Илья Не-не-не. Так нельзя. Можно нарваться на чтение порта в нестабильном состоянии. Передатчик и приёмник должны быть синхронизированы с точностью до такта. Чтение первого байта любого пакета всегда должно отставать на некоторое (фиксированное!) число тактов от записи этого байта (и у нас должна быть возможность выбрать величину отставания). Если момент чтения сдвигается относительно момента записи (от пакета к пакету; в пределах пакета он точно двигаться не будет), то я бы не стал гарантировать работоспособность. Ага, Ты тоже это понимаешь. Но если мы можем синхронизироваться в пределах передачи байта (т.е. в пределах 3-х тактов), то это значит, что мы можем синхронизироваться и в пределах пакета. Илья
  7. .rep -- это директива ассемблера (в частности, gas), повторяет фрагмент до .endr указанное число раз. И за пару тактов не получится. Передатчик не может тратить меньше трёх тактов на передачу байта. Вот если передатчик ПЛМ'ка какая... то тут возникает вопрос со стабильностью приёма, т.к. входной тракт вывода порта микроконтроллера требует стабильного состояния сигнала в течении двух тактов минимум. Илья
  8. С прерыванием от таймер -- это тоже хорошо. И, кстати, в икс-меге обязательно нужно возвращаться из прерывания (но не обязательно в то же место, где прерывание начали обрабатывать; в меге можно было бы вообще не возвращаться из прерыания от таймера, а только убрать адрес возврата из стека). Но если памяти хватает, то можно тупо повторить 1536 раз фрагмент: in reg, PORT_PIN st Y+, reg rjmp 1f 1: Вот так: .rep 1536 in reg, PORTx_PIN st Y+, reg rjmp 1f 1: .endr Если устраивает три такта на передачу байта, то rjmp заменить на nop. Илья
  9. На картинке явно видно, что IF[n] -- это тригер. Значит событие будет запомнено и обработано после разрешения битом IEN[n]. (Ну, тут ещё возникает вопрос соответствия картинки, как и вообще документации, реальному положению дел :-) В STM32F429 это не так. Конечно, если запрос зафиксировали в pending регистре, то он будет обработан. Илья
  10. Скорее нет. На картинке (которая Fig 4.1.) должно быть явно видно. Но по тексту: сначала выставляется флаг, потом флаг маскируется (qualified), затем флаг запоминается в pending регистре. Так что если маска наложена, то флаг не запомнится. Илья
  11. Т.е. шина должна быть способна прокачать 7.5 МБ в секунду. Ну, наверное можно попробовать. У меня есть работающее решение, но там всего 16 байтов в пакете. Передатчик и приёмник тактируются одним сигналом (32МГц), передача пакета синхронизируется внешним (по отношению к передатчику и приёмнику) сигналом. Приём и передача выполняется без сигнала строба. Каждые 3 такта принимаю байт. Такие большие пакеты я бы попробовал передавать и принимать с помощью DMA и таймеров. Синхронный запуск передачи и приёма решаем. Лишь бы у каждого был свободный порт целиком. Кроме того, нужно проверить влияние конфликтов доступа к памяти со стороны DMA и ядра. Впрочем, и на асме можно: ; приёмник .rep 1536 in r16, PORTx_PIN st Z+, r16 nop .endr ; передатчик .rep 1536 ld r16, Z+ out PORTy_OUT, r16 .endr Если будет менее трёх тактов, то приём, я думаю, будет нестабильным, т.к. на установку бита в схеме приёма микроконтроллера нужно два такта. Я то вместо nop'а полезную работу ещё выполняю: данные идут со скоростью 1.5 МБ в секунду и их нужно обработать (терять 16 тактов каждые 10 мкс -- непозволительная роскошь, это же 5% времени). Ну и если пакеты идут раз в мс, то на синхронизацию будешь тратить в сто раз меньше, чем я. А я трачу как раз около 10% времени на это. Илья Вспомнил. Может не получиться. Надо уточнять минимальный цикл DMA. Он запросто может быть больше пяти тактов. Илья
  12. Stream -- это поток. Channel -- это канал. Каждый поток настраивается независимо. Не знаю, как у F40x, а у ST32F429 в разных потоках можно использовать даже одно и то же событие для запуска транзакции (см. DMA2, Stream1:ch6, Stream3:ch6, Stream6:ch0 -- все они могут срабатывать по сигналу TIM1_CH1). Думаю, у F40x точно так же. Илья
  13. См. документацию на свой камень. Для stm32f42xx (RM0090, стр.377): если запретить прерывание на пине (маской), то прерывания не будет, до pending request register событие не дойдёт. Сам попадался. Илья
  14. [CENSORED] "Сразу" -- это когда? На следующем такте SCK? Через 10 мкс? Через 10 мс? Через 10 секунд? Ага, "сразу" -- точный инженерный термин. Слейв может подготовить данные и сообщить об этом мастеру. Поезд подождёт, пока ему разрешат ехать дальше. Грамотный разработчик сначала анализирует требования ко времени реакции слейва/системы и т.д. Кстати, как реализовать команду "чтение статуса"? Или это единственная команда? Или всё же нужно сделать задержку/паузу на время подготовки слейвом ответа на команду мастера? И как эту задержку можно уменьшить (если нужно уменьшать)? Илья