Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 15:43:00

И в ODR будет 0x5555.

Если старшее полуслово не используется, то почему бы и нет? Вполне работоспособная схема. Хоть и теоретически это UB.
Я, кстати, в какой-то железяке так гонял байты при помощи DMA - именно из массива uint8_t. Чтобы обеспечить параллельный интерфейс. Старшее полуслово не использовал, поэтому никаких косяков не было. Понятно, что если бы возникла необходимость использовать ногодрыг на пинах старшего полуслова, пришлось бы уже от uint8_t в массиве переходить на uint32_t и писать не в ODR, а в BSRR.
Последний раз редактировалось Eddy_Em Вт дек 17, 2019 15:45:01, всего редактировалось 1 раз.

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 15:45:14

Если закоментировать LCD_WR_H; изображения нет.
А откуда ему взяться, если ты в примерно половине случаев WR=1 не делаешь?

Я думал что такой подход кому-то поможет. Применять или нет дело программера.
Мы же с Reflector показали, что это НЕ РАБОТАЕТ.

Добавлено after 1 minute 21 second:
Если старшее полуслово не используется, то почему бы и нет?
Ты вообще читаешь что люди пишут? Используется и влияет!

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 15:47:16

https://www.youtube.com/watch?v=uv0sqAAMHFA

А что это там за черная фиговина прицеплена к "таблетке"? Холл что ли?

Добавлено after 50 seconds:
Ты вообще читаешь что люди пишут? Используется и влияет!

На кой черт я буду лезть дальше двух-трех последних комментариев? Как будто делать нехрен, только всю ветку читать…

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 15:51:02

И ведь в RM есть прямой запрет так делать, а нет, всё равно советуют...

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 15:55:06

VladislavS, а не пофиг ли, что в RM запрещено?
Еще раз: если из порта используется только половина ног, скажем младшее полуслово, то вполне нормально писать при помощи DMA байтики в ODR! Это не приведет к поломке устройства или UB, покуда ноги второго полуслова настроены как аналоговые входы или alternate function.

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 15:58:24

Черная - пьезопищалка. Изначально было про 8бит АЦП.

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 16:04:27

Еще раз: если из порта используется только половина ног, скажем младшее полуслово, то вполне нормально писать при помощи DMA байтики в ODR!

Sergi писал, что у него на второй половине порта, которая перезаписывается случайным образом, висит WR, энкодер, кнопки и EPROM. По-моему тут и один дисплей не должен нормально работать, разве что на очень низкой скорости, но если очень хочется отлавливать непонятно откуда взявшиеся баги, то почему нет :) И это все ради одной или двух лишних инструкций которые добавятся если в половинку порта писать через BSRR.

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 16:09:03

Reflector, ну, понятно к чему дело - попытка сэкономить время и объем памяти, т.к. через BSRR пришлось бы городить преобразование 8 бит в 32 (единички - в одну половинку, нулики инвертировать - и в другую). А потом при помощи DMA гнать этот массив.
А насчет АЦП - если работает, ну и хрен с ним! Скажем, в STM8 было важно, в какой последовательности считываются полуслова (кажись, это в АЦП было, хотя точно уж не помню). Здесь же никаких флагов нет. Единственная проблема - невыровненный доступ. Но, к счастью, STM32 - little endian, а читать надо младший байт. Так что, все ОК.

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 16:23:46

VladislavS, а не пофиг ли, что в RM запрещено?
Да, знаю, а если не будет работать "перепишешь модуль ядра".

Добавлено after 5 minutes 55 seconds:
через BSRR пришлось бы городить преобразование 8 бит в 32 (единички - в одну половинку, нулики инвертировать - и в другую).
Ууууу, да ты ещё и не знаешь как BSRR работает! Куда я попал...

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 16:35:51

VladislavS, в смысле не знаю? Одна половинка регистра устанавливает биты, другая - гасит. Что-то ты гонишь!

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 16:40:00

Если установлены и Set, и Reset биты одновременно, то приоритет имеет Set. Соответственно, ничего инвертировать и в другую половинку гнать не надо. Это, кстати, тоже в RM написано. Да кто же его читает...

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 16:57:35

Это да, в левую половинку можно просто FFFF положить, а не инверсию нулей.

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 17:10:51

Нельзя туда FFFF положить! Иначе UB будет. Только FF куда нужно.
Да кто же его читает...

Есть такое.

Re: STM32 новичку в ARM что к чему

Вт дек 17, 2019 18:45:38

Почему вдруг?
Если мне надо в порт положить, например, число 0x5555, можно его просто в ODR записать, либо в BSRR положить 0xFFFF5555.

Или, если надо в младший байт число 0x55 записать, просто в BSRR положить 0x00FF0055. Какие-то дополнительные манипуляции с нулями (0x55 => 0xAA => 00AA0055) не нужны.

Re: STM32 новичку в ARM что к чему

Ср дек 18, 2019 03:59:05

WiseLord если нужно только записать данные использовать надо ODR, если нужно изменить значение порта есть два путя
1. через read IDR/ODR-modify-write ODR
2. Атомарный write BSRR(установка/сброс) регистр. либо просто атомарный BRR(сброс)

BSRR регистр за один вызов изменяет значение порта, это нужно если работает ОС и несколько потоков могут одновременно получить доступ к порту.

BRR только сбрасывает.

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

Re: STM32 новичку в ARM что к чему

Ср дек 18, 2019 06:34:20

Проверил скорость вех вариантов.
BSRR победил как всегда :)) .
Код:
void lcd_send_cmd(uint8_t cmd)
{
    LCD_DC_L;
    LCD_WR_L;
 //GPIOB->ODR &=~0xff00;GPIOB->ODR |= (cmd<<8);   //88596 tics
   GPIOB->BSRR = 0xff000000 | (cmd<<8);                   //66660 tics
 //LCD = cmd;                                                              //72593 tics
    LCD_WR_H;
      LCD_DC_H;
};

Re: STM32 новичку в ARM что к чему

Ср дек 18, 2019 07:24:40

Если не используется несколько потоков, с атомарным доступом не надо морочиться.
Кроме потоков есть ещё и прерывания.

Программируете стандартно.
Через BSRR это и есть стандартно, ибо тупо быстрее, чем R-M-W ODR.

Re: STM32 новичку в ARM что к чему

Ср дек 18, 2019 07:30:53

VladislavS есть переменная которая меняется скажем uint8_ t X, как будешь записывать значение в порт через BSRR? Покажи код.

Прерывания другая история, это все равно контроллируемый код и однопоточный.

Re: STM32 новичку в ARM что к чему

Ср дек 18, 2019 08:35:22

VladislavS есть переменная которая меняется скажем uint8_ t X, как будешь записывать значение в порт через BSRR?

Да элементарно: GPIOX->BSRR = 0xff0000 | X

Re: STM32 новичку в ARM что к чему

Ср дек 18, 2019 13:49:54

VladislavS есть переменная которая меняется скажем uint8_ t X, как будешь записывать значение в порт через BSRR? Покажи код.
Ну, в отличии от Эдика, я парень хитрый. К тому же, ты решил поиграть на моём поле. :)
Код то будет простой.
Код:
uint8_t X = GPIOA->IDR;         // Сделаем чтобы X была переменной, а не константой
PinList<GpioB<0xFF00>> bus8bit; // Определим шину на старшие 8 бит GPIOB
bus8bit = X;                    // Запишем в неё данные
А вот во что это скомпилируется, это как раз и интересно. А вариантов тут может быть два.

1. На процессоре STM32F103 без байтового доступа к регистрам
Компилятор выберет вот такой метод и запишет через BSRR
Код:
  template<uint32_t PM=PinsMask>
  static void inline write(uint16_t data)
  {
    if constexpr (PM == 0xFFFF)
      base()->ODR = data;
    else
      base()->BSRR = (PM << 16) | (data & PM);
  }
Листинг
Код:
//uint8_t X = GPIOA->IDR;
        LDR.N    R1,??main_0      ;; 0x40010808
        LDR      R0,[R1, #+0]
//PinList<GpioB<0xFF00>> bus8bit;
//bus8bit = X;   
        LSLS     R0,R0,#+24
        LSRS     R0,R0,#+16
        ORR      R0,R0,#0xFF000000
        STR      R0,[R1, #+1032]


2. На процессоре STM32F303 c байтовым доступом к регистрам
Компилятор выберет вот такой метод и запишет через ODR
Код:
template<uint32_t PM=PinsMask>
static void inline write(uint16_t data)
{   
  if constexpr (PM == 0xFFFF)
    base()->ODR = data;
  else if constexpr (PM == 0x00FF)
    *(volatile uint8_t*)&base()->ODR = data;
  else if constexpr (PM == 0xFF00)
    *((volatile uint8_t*)&base()->ODR + 1) = data >> 8;
  else
    base()->BSRR = (PM << 16) | (data & PM);
}
Листинг
Код:
//uint8_t X = GPIOA->IDR;
        LDR.N    R0,??main_0      ;; 0x48000010
        LDR      R1,[R0, #+0]
//PinList<GpioB<0xFF00>> bus8bit;
//bus8bit = X;   
        STRB     R1,[R0, #+1029]


Ну вот как-то так.

Прерывания другая история, это все равно контроллируемый код и однопоточный.
Хм. Если в основном цикле я делаю неатомарный доступ R-M-W к порту и из прерывания к этому же порту идёт обращение... То всё!



Добавлено after 4 hours 17 minutes 21 second:
Ну куда же вы все разбежались? Я ещё не показал коронный номер, которому меня Reflector научил. :)

Копируем младшие 8 бит порта в старшие 8 бит в обратном порядке: PB0->PB15, PB1->PB14, PB2->PB13, PB3->PB12, PB4->PB11, PB5->PB10, PB6->PB9 и PB7->PB8.
Код:
PinList<PB_7, PB_6, PB_5,  PB_4,  PB_3,  PB_2,  PB_1,  PB_0 > bus_low;
PinList<PB_8, PB_9, PB_10, PB_11, PB_12, PB_13, PB_14, PB_15> bus_high;
bus_high = bus_low;
//Листинг
        LDR.N    R1,??main_0      ;; 0x48000410
        LDRB     R0,[R1, #+0]
        RBIT     R0,R0
        LSRS     R0,R0,#+24
        STRB     R0,[R1, #+5]
Ответить