Авторизация
Зарегистрироваться

Электронная бумага: пишем драйвер методом научного тыка

В предыдущей статье я рассказывал, как я затарился электроннобумажными дисплеями и даже сделал для них блок питания.

Наконец, пришли заказанные для них печатные платы и теперь можно заняться программным обеспечением. То, что описано ниже, касается только ED060SC4(LF) или LB060S01-RD02. Отличие в названии на одну букву, даже ту, что в скобке — и работать ничего не будет. Когда я задумал это безнадежное занятие, мне казалось, что я нашел кучу информации и исходников, и запустить этот дисплей проблемой не будет, несмотря на очень убогие спецификации от производителей. Не тут-то было, в каких-то местах описание оказалось на дисплей, название которого отличалась на одну букву, а в других — алгоритм просто не работал. В наше время верить нельзя никому, даже самому себе. Мне — можно.


В целях природы обуздания,
В целях рассеять неученья
Тьму
Берём картину мироздания – да!
И тупо смотрим, что к чему…

Целых два дня я тупо перебирал очередность разных сигналов и задержки между ними, не зная, жив ли еще дисплей. Не было даже намеков на появившуюся точку. И в один прекрасный момент — вуаля! — получите целую линию мусора. Всё, больше ничего и не надо, все остальное, дело техники, теперь он никуда не денется.


Теперь расскажу, как все-таки удалось запустить это чудо. На истину в последней инстанции я не претендую, как заработало — так и опишу.

Для прорисовки экрана нужны следующие сигналы — сначала начало кадра, потом 600 строк, каждая имеет старт, потом данные и стоп. Завершается все концом кадра. За один пиксель отвечает два бита, комбинация 01 — черный цвет, 10 — белый, остальные — без изменения.
Таким образом, для одной строки из 800 пикселей нужно передать 200 байт.

Схема простая — источник питания, описанный в прошлой статье, STM32F103C8 для управления дисплеем и ESP32 на все про все, но пока его не используем.


Ардуним для начала — определяем макросы, которые будут управлять сигналами.

Нажми меня
// ****************************************************
// power control
// en positive PB6
// en negative PB7
// en VDD      PB8
//
#define INIT_POWER GPIOB->regs->CRL  &=  0x00FFFFFF;\
                   GPIOB->regs->CRL  |=  0x11000000;\
                   GPIOB->regs->CRH  &=  0xFFFFFFF0;\
                   GPIOB->regs->CRH  |=  0x00000001;\
                   GPIOB->regs->BRR  = 0x01C0;                 

#define PWR_VDD_ON  GPIOB->regs->BSRR = 0x0100;
#define PWR_VDD_OFF GPIOB->regs->BRR = 0x0100;
#define PWR_POS_ON  GPIOB->regs->BSRR = 0x0040;
#define PWR_POS_OFF GPIOB->regs->BRR = 0x0040;
#define PWR_NEG_ON  GPIOB->regs->BSRR = 0x0080;
#define PWR_NEG_OFF GPIOB->regs->BRR = 0x0080;
#define PWR_ALL_ON  GPIOB->regs->BSRR = 0x01C0;
#define PWR_ALL_OFF GPIOB->regs->BRR = 0x01C0;
// ****************************************************

// SPV and SPH high, and all other pins low
  // data
  #define DATA_PORT  GPIOA
  // CL  LE OE CPH GMODE SPV CKV
  // CL PB9
  #define CL_PORT  GPIOB  
  #define CL_PIN   9  
  // LE PC13  
  #define LE_PORT  GPIOC  
  #define LE_PIN   13  
  // OE PC14  
  #define OE_PORT  GPIOC  
  #define OE_PIN   14  
  // CPH PC15  
  #define CPH_PORT  GPIOC  
  #define CPH_PIN   15  
  // GMODE PB0  
  #define GMODE_PORT  GPIOB  
  #define GMODE_PIN   0  
  // CKV PCB2  
  #define CKV_PORT  GPIOB  
  #define CKV_PIN   2  
  // SPV PB1  
  #define SPV_PORT  GPIOB  
  #define SPV_PIN   1  

// DATA
// PC0...PC7
// PA0...PA7
#define INIT_DATA  DATA_PORT->regs->CRL  = 0x33333333; DATA_PORT->regs->BRR  = 0xFF;  

#define INIT_CL    CL_PORT->regs->CRH &= ~(0xF << ((CL_PIN &0x7)<<2)); CL_PORT->regs->CRH |= 0x3 << ((CL_PIN &0x7)<<2);
#define CL_IDLE    CL_PORT->regs->BRR  = 1<<CL_PIN;  // reset
#define CL_ACTIVE  CL_PORT->regs->BSRR = 1<<CL_PIN;  // set


#define INIT_LE    LE_PORT->regs->CRH &= ~(0xF << ((LE_PIN &0x7)<<2)); LE_PORT->regs->CRH |= 0x3 << ((LE_PIN &0x7)<<2);
#define LE_IDLE    LE_PORT->regs->BRR  = 1<<LE_PIN;  // reset
#define LE_ACTIVE  LE_PORT->regs->BSRR = 1<<LE_PIN;  // set


#define INIT_GMODE    GMODE_PORT->regs->CRL &= ~(0xF << ((GMODE_PIN &0x7)<<2)); GMODE_PORT->regs->CRL |= 0x3 << ((GMODE_PIN &0x7)<<2);
#define GMODE_IDLE    GMODE_PORT->regs->BRR  = 1<<GMODE_PIN;  // reset
#define GMODE_ACTIVE  GMODE_PORT->regs->BSRR = 1<<GMODE_PIN;  // set

#define INIT_CKV    CKV_PORT->regs->CRL &= ~(0xF << ((CKV_PIN &0x7)<<2)); CKV_PORT->regs->CRL |= 0x3 << ((CKV_PIN &0x7)<<2);
#define CKV_IDLE    CKV_PORT->regs->BRR  = 1<<CKV_PIN;  // reset
#define CKV_ACTIVE  CKV_PORT->regs->BSRR = 1<<CKV_PIN;  // set

#define INIT_SPV    SPV_PORT->regs->CRL &= ~(0xF << ((SPV_PIN &0x7)<<2)); SPV_PORT->regs->CRL |= 0x3 << ((SPV_PIN &0x7)<<2);
#define SPV_IDLE    SPV_PORT->regs->BRR  = 1<<SPV_PIN;  // reset
#define SPV_ACTIVE  SPV_PORT->regs->BSRR = 1<<SPV_PIN;  // set


#define INIT_OE    OE_PORT->regs->CRH &= ~(0xF << ((OE_PIN &0x7)<<2)); OE_PORT->regs->CRH |= 0x3 << ((OE_PIN &0x7)<<2);
#define OE_IDLE    OE_PORT->regs->BRR  = 1<<OE_PIN;  // reset
#define OE_ACTIVE  OE_PORT->regs->BSRR = 1<<OE_PIN;  // set

#define INIT_CPH    CPH_PORT->regs->CRH &= ~(0xF << ((CPH_PIN &0x7)<<2)); CPH_PORT->regs->CRH |= 0x3 << ((CPH_PIN &0x7)<<2);
#define CPH_IDLE    CPH_PORT->regs->BRR  = 1<<CPH_PIN;  // reset
#define CPH_ACTIVE  CPH_PORT->regs->BSRR = 1<<CPH_PIN;  // set



void Vclock()
{
  CKV_ACTIVE
  CKV_IDLE    
}

void Hclock()
{
  CL_ACTIVE
  CL_IDLE    
}

void PowerOn(void)
{
  PWR_VDD_ON
  delay(30);     
  PWR_NEG_ON
  delay(5);     
  PWR_POS_ON  
}

void PowerOff(void)
{
  PWR_POS_OFF    
  delay(5);     
  PWR_NEG_OFF
  delay(5);     
  PWR_VDD_OFF
}


Ведь правду говорят — ардуино это для совсем отстойных, которым лень думать и документацию читать.
Старт кадра выглядит так:


и код:
void start_frame()
{
  GMODE_ACTIVE
  delay_us(1);
  CKV_ACTIVE
  delay_us(1);
  SPV_IDLE 
  delay_us(1);
  CKV_IDLE  
  delay_us(1);
  CKV_ACTIVE
  delay_us(1);
  SPV_ACTIVE
  delay_us(1);
}

Потом передаем 600 строк, каждая начинается так:


Уж все безумно просто:

void start_row()
{
  CPH_IDLE
}


Завершение строки очень критично, чуть что не так — и никакого изображения не будет:


Код, соответственно:

void stop_row()
{
  CPH_ACTIVE
  CKV_IDLE  
  Hclock();
  CKV_ACTIVE  
  OE_IDLE
  delay_us(2);  
  OE_ACTIVE  
  LE_ACTIVE
  LE_IDLE  
}

И завершаем кадр:


Котд:

void end_frame()
{
GMODE_IDLE
delay_us(1);
Vclock();
}


Все вместе образует вот такое безобразие:


И, наконец, тестовый код:

Нажми, если хочешь
<code>uint8_t data;


void setup()
{
  INIT_POWER

  GPIOB->regs->CRH  &=  0xFFFFF0FF;    //pinMode(PB10, OUTPUT); 2MHz
  GPIOB->regs->CRH  |=  0x00000200;  

  // USB pin open drain
  GPIOA->regs->CRH  &=  0xFFFFF0FFF;
  GPIOA->regs->CRH  |=  0x000000600;  
  GPIOA->regs->BRR = 1<<10;   // digitalWrite(PA10,0);     
  delay(100);
  GPIOA->regs->BSRR = 1<<10;   // digitalWrite(PA10,1);   
  Serial.begin();
  Serial.println("E-paper test");


  INIT_DATA
  INIT_CL
  CL_IDLE

  INIT_GMODE
  GMODE_IDLE

  INIT_CKV
  CKV_IDLE 

  INIT_SPV
  SPV_ACTIVE 

  INIT_OE
  OE_IDLE

  INIT_CPH
  CPH_ACTIVE

  INIT_LE
  LE_IDLE  

  data=0xaa;
}



void loop() 
{
  uint8_t tdata;

  GPIOB->regs->BSRR  = 1<<10;  // LED on

  PowerOn();
  delay(100);  
 

  for (uint16_t k=0; k<6; k++)
  {
    static bool even=false;
    start_frame();
    // write frame
    for (uint16_t i=0; i<600; i++)
    {
      // wrire row
      if (even) tdata = data;  
      else      tdata = ~data;    
      if((i & 0x3f)==0) even = !even;
      start_row();
      //data = 0;   
      for (uint16_t j=0; j<200; j++)
      {
        if((j & 0x0f)==0) tdata = ~tdata;
        DATA_PORT->regs->BRR  = 0xFF;  
        DATA_PORT->regs->BSRR  = tdata;  
        Hclock();      
      }
      stop_row();
    }
  }
  data = ~data;
  

  end_frame();

  delay(10);  
  PowerOff();
  GPIOB->regs->BRR  = 1<<10;  // LED off
  delay(2000);  
}


Извиняйте, если уж сильно тривиально все выглядит. Если бы мне все это кто-то рассказал до того, как я эту возню затеял…
Может, кому другому поможет.

А это то, что этот тест делает — рисует шахматную доску. Смотрим скорость обновления — получается более, чем достойно, судите сами:



За один цикл прорисовки черные точки получить не удастся, получаются серые. У меня для получения черного цвета нужно повторить передачу кадра раз 6 — для пущей надежности я передаю его 8 раз.
В реальном устройстве присутствует lookup table, где хранятся данные о длительностях сигналов в зависимости от температуры и интенсивности черного. Почему-то производители сделали большой секрет из этих данных, поэтому имеем то, что имеем. У реального контроллера дисплея куча памяти, где он хранит изображение и следующее формируется в зависимости от предыдущего — не нужно полностью стирать изображение и потом рисовать все по новой — обновление происходит с учетом текущего состояния, поэтому его можно выполнить быстрее. Но оперативной памяти нужно много — ведь у экрана 480 000 пикселей.
По схеме видно, что микроконтроллер у меня дохленький, у него всего 20К ОЗУ и 64К флеш.
Но я использую буфер длиной всего 200 байт, и каждую строку просчитываю перед выводом.
Что-то подобное я использовал много лет назад, когда делал полетный контроллер для игрушечного самолетика и выводил изображение поверх картинки с видеокамеры — там, если склероз не подводит, вообще у контроллера было 4К ОЗУ. И сделано было еще интереснее — пока контроллер прямого доступа выбрасывал одну строку, процессор просчитывал следующую. В итоге использовалось 4 буфера — два для белого и 2 для черного.



Это было небольшое отступление. В реальных дисплеях производители обычно используют 16 градаций серого, но у любителей получается и 32 использовать.


Но мне это не надо, двух уровней черного для моих целей достаточно и я легко это сделаю использованием количества перезаписываний кадра.


Алгоритм с многократной перезаписью кадра выглядит убого, если у кто знает, как сделать лучше — пожалуйста, напишите в комментариях. Моя благодарность не будет иметь границ (в разумных пределах).

Следующим шагом будет добыча погоды из интернета и формирование полного кадра, но для этого будет использоваться ESP32, а STM32 будет играть роль тупого драйвера. Печатную плату тоже планирую переделать — контрольные точки уже не нужны, зато надо добавить управление питанием, планируется использовать литиевый аккумулятор. Нужно добавить зарядку и позаботиться о уменьшении потребления энергии устройством.
А пока можно немного размяться и с STM32:


С ESP32 тоже не все так просто — при попытке выделить массив под кадр больше 96К, линкер отказывается работать, заявляя что все, памяти у него для вас больше нет. А где же ваши хваленые 320K Data RAM? При попытке выбросить SPI пакет, непрерывного потока не получается — после каждых 64 байта, кажется, идет разрыв несколько микросекунд. Но кому сейчас легко — будем бороться.
Небольшое скакание по исходникам показало, что посылка действительно разбивается, и это происходит в HAL — наверно, разработчики контроллера имели какую-то причину? Или они просто злобные Буратины, вся цель жизни которых — нагадить мне?
Дополнительная информация
void spiWriteNL(spi_t * spi, const void * data_in, uint32_t len){
    if(!spi) {
        return;
    }
    size_t longs = len >> 2;
    if(len & 3){
        longs++;
    }
    uint32_t * data = (uint32_t*)data_in;
    size_t c_len = 0, c_longs = 0;

    while(len){
        c_len = (len>64)?64:len;
        c_longs = (longs > 16)?16:longs;

        spi->dev->mosi_dlen.usr_mosi_dbitlen = (c_len*8)-1;
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
    spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif
        for (size_t i=0; i<c_longs; i++) {
            spi->dev->data_buf[i] = data[i];
        }
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
        spi->dev->cmd.update = 1;
        while (spi->dev->cmd.update);
#endif
        spi->dev->cmd.usr = 1;
        while(spi->dev->cmd.usr);

        data += c_longs;
        longs -= c_longs;
        len -= c_len;
    }
}

Библиотеку можно подправить, но при первом же обновлении мои правки накроются медным тазом. Пусть будет, как есть — не особо мешает.

Еще вариант — поставить дополнительную SPI RAM к дохленькому контоллеру. Где ее купить недорого — пока не нашел. А ставить мощный контроллер в качестве драйвера не особо хочется — у них и цена кусается, и слишком много ног, одни проблемы с пайкой.

RP2040 с его 264KB SRAM и программируемыми выводами выглядит хорошо, только там SRAM сегментирована по 64KB — опяь могут быть проблемы с буфером кадра. И кушать много изволит в спящем режиме. Что-то душа к нему не лежит. Короче, куда не кинь — везде клин, нет в жизни счастья :)

Гда брать погоду — еще одна проблема. Меньше всего ограничений у open-meteo.com, но они, как настоящие джентельмены, меняют правила по ходу игры. А поначалу смотрелось неплохо — регистрация не нужна, информацию можно брать по максимуму и безо всяких ограничений на запросы. Прогноз, надо сказать, не особо точный и еще и глюки имеются — как-то за окном шел дождь, а они на осадки на текущий день прогнозировали отрицательную величину. Интересно, это как?
Наверно, самый популярный сайт — это openweathermap.org, но они очень хотят денег и всячески затрудняют жизнь халявщиков. И необходимость регистрации и ограничение на запросы не радуют, хотя ограничения на запросы вполне разумные. Но информации open-meteo дает больше, хоть и неправильной.
Dark Sky куплена Apple, так что ловить там уже нечего.
Первые тесты выглядят так (прогноз с open-meteo):


Пока статья писалась — и новая схема поспела, можете покритиковать при желании, только не сильно:



Антенна оказалась рядом с металлом дисплея. Он весь покрыт металлом, а плата будет к нему приклеена.
Когда коту делать нечего — он платы разводит. Переделываем все так, чтобы антенна выступала из-за экрана:


Почему эта статья не на Хабре? Причин много — во-первых, там все рисуют какого-то бегемота в колпачке, а я даже не знаю, откуда он взялся, неудобно как-то (это про картинку слева, а про котенка с улицы Лизюкова я знаю).


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


На английском, было дело, я наваял кучку сайтов, доверившись Гуглу и его репутации — через какое-то время их прихлопнули. Больше не хочется время терять.
А здесь хоть плюсик поставят :) — уже видно, что не зря старался.
В комментариях часто здравую идею подскажут — тоже польза.
Ну и писать на английском — это все-таки труд, а на русском — развлечение. Графоманы подтвердят.

Кстати, анонс — Марио таки ограбил банк, так что впереди много интересного.


Что это и с чем это едят — можно посмотреть здесь и здесь.
Добавить в избранное +177 +265
свернуть развернуть
Комментарии (46)
RSS
+
avatar
+1
Марио таки ограбил банк, так что впереди много интересного.
Эти штуки вроде как по беспроводной связи могут «общаться», и если понять как то можно их по всему дому и не только расставить и выводить ту или иную информацию.
+
avatar
+8
Об этом и речь будет — там zigbee, и народ заставил их общаться. Впрочем, на первой ссылке все это есть, только у немцев найти можно больше деталей и реализаций. И ящик этот, впрочем, тоже из Неметчины приехал, там это дешевая и популярная игрушка. К home assistant их тоже подцепили.
+
avatar
0
А как называются?
+
avatar
0
Solum ST-GR29000
+
avatar
0
Сеньор Батон! Извините за тупость, я понажимал на все ссылки, а где сфера применения этой эл.бумаги. Если для ценников — то слишком дорого и уже не нужно. Эл.Бумага нужна там, где нет тока, в переносном сегменте. Я не прав?
+
avatar
0
Не обязательно. Если нет желания тянуть лишние провода — тот же ценник от батарейки работает много лет. Прогноз погоды на стенку, дисплеи умного дома. Вывеска где-то, например на комнате совещаний, которую могут использовать разные группы. Обновляться может через zigbee каким-то сервером резервирования. Гостевой бейджик. Игрушка для ребенка
+
avatar
0
Да не надо меня за эл. бумагу агитировать, это я и так знаю. Весь вопрос цены. А бейджик посетителю — ну да это круто, но надо ещё бы покрыть стразами от… ну чтоб для полной крутизны :-)
Лучше напишите конечный ценник на эти игрушки, вкл. все затраты и обслуживание и всё само собой прояснится!
Да, а сама статья про драйвера прекрасна — СПАСИБО ВАМ!
+
avatar
0
А смысл мне кого-то агитировать? И тем более цены считать — у меня это развлечение, а за него обычно сами платят. Бейджик — это просто реальное и кем-то реализованное применение, есть там стразы или нет — не в курсе :) Если он будет стоить порядка 5 евро — почему и нет? Насколько я в курсе, оптовая цена небольшого цифрового ценника 5...10 евро.
Статья про цифровые ценники лежит в черновиках, будет опубликована в начале следующего месяца. Там будет малая часть информации, в основном с чем я сам игрался.
А что со всем.этим делать — я и сам толком пока не знаю, там более, что у меня их больше полусотни. Бывшие в употреблении можно купить начиная с одного евро — правда, партия в 500 штук :)
+
avatar
0
Ну не цепляйтесь к словам! Я не с критикой вам писал. Ещё раз, СПАСИБО за ваш труд в деле популяризации эл. бумаги! Ну а про цены вААще круть — тем более 1 эуро за игрушку — это очень даже приемлемо для бейджика или ценника!!! Даже с учетом, что его могут с… ть, (тут синоним слова стащить!) :-)
Ждем статью про ценники!
+
avatar
  • vismyk
  • 01 июля 2023, 07:32
+6
Как всегда плюсую и снимаю панаму!
там все рисуют какого-то бегемота в колпачке, а я даже не знаю, откуда он взялся, неудобно как-то
С улицы им. генерала Александра Ильича Лизюкова в г. Воронеже же! ;)
+
avatar
+2
Про котенка с улицы Лизюкова я знаю, вот что на картинке слева — не в курсе.
+
avatar
  • vismyk
  • 01 июля 2023, 08:41
+4
А. Это я даже знать не хочу. ;)
+
avatar
+1
Отличие в названии на одну букву, даже ту, что в скобке — и работать ничего не будет.
Помню, в начале нулевых устанавливал родственникам внутренний винмодем Acorp — вот там намудохался с драйверами, оказывается, у внешне одинаковых моделей с буквами PIM и PIN в конце длинного индекса, разные драйверы, несовместимые между собой. Плюс ко всему традиционная акорповская кривизна драйверов и сайтов и общее слабое ещё развитие онлайна в те времена.
+
avatar
  • vismyk
  • 01 июля 2023, 08:00
+4
С буквами тут дело такое. ED060SC4(LF) — экран 2 поколения (VizPlex) и у него я не помню «близнецов» с другими буквами. Было несколько моделей, начинающихся на «ED060SC», а дальше разные буквы и цифры, но они обычно механически несовместимые (шлейфы торчат в разные стороны и заканчиваются разными разъёмами). Одно исключение — ED060SC8(LF), который механически и электрически совместим с ED060SC4(LF), но принадлежит уже к следующему поколению (Pearl) с улучшенным контрастом…
+
avatar
+1
Спасибо, любопытно было читать.
там какие-то страшные джуны, мидлы и тимлиды проходят интервью и получают оферы
Был когда-то там завсегдатаем, но злобные олдфаги постоянно норовили слить карму за безобидные комментарии только потому, что придерживались иного мнения.
P.S.
Что это и с чем это едят — можно посмотреть здесь и здесь.
Для второй ссылки нужен VPN, хотя итак можно догадаться, что там.
+
avatar
+4
Для второй ссылки нужен VPN, хотя итак можно догадаться, что там.
Странно, это немецкая микроконтроллерная конференция-болталка, абсолютно безобидная.
Ссылку поменял на другую, вроде должна работать.
+
avatar
  • jeepeg
  • 01 июля 2023, 08:28
+5
Кроме того, там какие-то страшные джуны, мидлы и тимлиды проходят интервью и получают оферы.
Я думал одного меня там это раздражает.
А платы вы в чем разводите?
+
avatar
+7
Кикад
+
avatar
0
Для прорисовки экрана нужны следующие сигналы — сначала начало кадра, потом 600 строк, каждая имеет старт, потом данные и стоп. Завершается все концом кадра. За один пиксель отвечает два бита, комбинация 01 — черный цвет, 10 — белый, остальные — без изменения.
Таким образом, для одной строки из 800 пикселей нужно передать 200 байт.
А с microLCD от проектора тоже так можно? :)
+
avatar
+2
Не знаю, проекторы я ломал только с зеркалами — была мысль переделать на ультрафиолет. Но так и не доделал.
+
avatar
0
А что за МК делал оверлей в полетном контроллере?
И какой формат видео шел с камеры?
+
avatar
+3
Какой-то MSP430, формат PAL.
+
avatar
0
спасибо!
+
avatar
0
Это реально мясо!
+
avatar
+17
Чел, ты нереально крут
+
avatar
  • sav13
  • 01 июля 2023, 12:21
+2
Проект достойный GITHUB и HABR

С ESP32 тоже не все так просто — при попытке выделить массив под кадр больше 96К, линкер отказывается работать, заявляя что все, памяти у него для вас больше нет. А где же ваши хваленые 320K Data RAM
Те кто подключают LCD дисплеи высокого разрешения используют модули с PSRAM
Интересно, ESP32S3 по параллельному интерфейсу будет работать с этим дисплеем?

Библиотеку можно подправить, но при первом же обновлении мои правки накроются медным тазом. Пусть будет, как есть — не особо мешает.
Идеально подружить это все с Adafruit GFX через Framebuffer. Там всего то нужно свою функцию обновления экрана из FB прикрутить. Тогда и с обновлениями будет полегче

Кроме того, там какие-то страшные джуны, мидлы и тимлиды проходят интервью и получают оферы. Может, это больно?
И получают кучу минусов )))
К счастью, там попадаются статьи вроде вашей (правда на 90% переводы), поэтому и есть пока еще что почитать
+
avatar
  • NeO928
  • 01 июля 2023, 12:24
+5
Как в известном меме: «Ничего не понял, но очень интересно!» )
+
avatar
  • berk
  • 01 июля 2023, 13:11
0
Здорово!
+
avatar
0
там SRAM сегментирована по 64KB — опяь могут быть проблемы с буфером кадра
Вот где-то тут и начинает хотеться плакать. Потому, что в каждом доме есть PC-совместимый компьютер, где всех этих ограничений с ОЗУ нет, и скорость процессора позволяет ни в чём себе не отказывать… Только вот во всех виндовсах запретили доступ к портам и прерываниям, начиная с WinXP :(((

А во времена WinME я баловался изучением алгоритма работы I2C шины монитора, которая в VGA/DVI кабеле. Через VESA функции BIOS видеокарты находил адреса всех I2C портов, а потом уже из Виндовса, запрещал прерывания и читал/писал в тот порт.
Программ, которые умеют крутить яркость/контрастность и прочее для ЭЛТ мониторов Samsung ещё не было. Была только сервисная программа Samsung, работавшая через специальную LPT-плату. А у меня то же самое через видеокарту получилось! Эх хорошие времена были для программирования.
+
avatar
  • ewavr
  • 01 июля 2023, 13:44
+1
посылка действительно разбивается, и это происходит в HAL — наверно, разработчики контроллера имели какую-то причину? Или они просто злобные Буратины, вся цель жизни которых — нагадить мне?
А DMA там можно использовать? Или не править ту библиотеку, а положить рядом свою?

только там SRAM сегментирована по 64KB
Разработчики времен MS-DOS читают с недоумением. У них тоже были сегменты по 64К, и жили — не тужили.
+
avatar
0
по 64К, и жили — не тужили
Ну не так уж и не тужили. Почти везде было ограничение на размер файлов в 64 кб. А те программы, что и умели работать с большими массивами данных, в 100% случаев были привязаны ко всяким emm386.exe и himem.sys. Сами не хотели работать с адресами ОЗУ выше 1 Мб. А это не только дополнительные заморочки с настройкой окружения, но и минус быстродействие.

Возможно чуть полегче жилось пользователям других расширителей памяти типа DOS4GW, но ни разу не видел, чтоб это использовалось в обычных программах (не играх).

А в WinME + Delphi7 можно было объявлять массивы хоть 10 Мб, и не парится насчёт того, как туда обращаться!
+
avatar
0
Сами не хотели работать с адресами ОЗУ выше 1 Мб
Так если у пользователя был emm386 и в верхней памяти что-то было, а вы сами с ней работать начнете — затрете же. А так, насколько я помню, надо было в защищенный режим уйти, создать сегмент на всю память, загрузить его, например, в ES, после чего вернуться обратно — и всё, адресуй сколько хочешь.
А в WinME + Delphi7 можно было объявлять массивы хоть 10 Мб, и не парится насчёт того, как туда обращаться!
Это 32-битная ось, тут у процесса 4 ГБ виртуального адресного пространства. Естественно, 10 МБ — не вопрос для неё, даже 256 МБ и 1 ГБ (при определенных условиях) можно было выделять непрерывным блоком.
+
avatar
+2
А DMA там можно использовать? Или не править ту библиотеку, а положить рядом свою?
Она там и используется.
С ESP32 глубоко разбираться лениво, тем более, что там многое не описано, а доступно в виде библиотек. По крайней мере документации с точностью до каждого бита я не видел.
Да и не особо мешает — потеря скорости передачи процент-другой, а на изображение не влияет.
Затык по скорости получается у SPI приемника STM32 — он обрабатывает прерывания и формирует сигналы не так быстро, как хотелось бы. Вот там можно было увеличить скорость уже раза в 2.
+
avatar
  • Nuts_
  • 01 июля 2023, 16:32
0
c esp32 там хотя бы разобраться со всем изобилием библиотек
я было начал писать статью но забил
+
avatar
0
Разработчики времен MS-DOS читают с недоумением.
Можно еще вспомнить обращение к видеопамяти SVGA через малюсенькое окошко (ЕМНИП, те же 64К, при размерах видеостраницы от пары сотен килобайт до примерно мегабайта). Увлекательное занятие.
+
avatar
+2
олько вот во всех виндовсах запретили доступ к портам и прерываниям, начиная с WinXP :(((
Port95NT.exe
+
avatar
  • vismyk
  • 01 июля 2023, 20:26
0
GiveIO.sys ;)
+
avatar
+1
Программ, которые умеют крутить яркость/контрастность и прочее для ЭЛТ мониторов Samsung ещё не было. Была только сервисная программа Samsung, работавшая через специальную LPT-плату. А у меня то же самое через видеокарту получилось! Эх хорошие времена были для программирования.
Так времена сейчас даже ещё веселее. Сейчас можно по этому I2C через обычный VGA порт обновить прошивку монитора или просто окирпичить.
Пару лет назад такую писал под Linux. Там, кстати, намного проще доступ до I2C. Даже прерывания отключать не надо.
+
avatar
0
Без запрета прерываний не получалось точные временные промежутки выдерживать (для измерения времени использовал счётчик тактов процессора, тогда ещё частота не плавала).

Чисто интересно: а примерно с какой частотой у вас получилось I2C передачу данных проводить, тем более с параллельно работающими чужими процессами?
+
avatar
0
Разве там частота критична? Это же не WS2801 со своим семейством.
DDC вроде как до 400 кГц должен тянуть, а 100 уж точно может. Да там это не так критично.
+
avatar
0
Без запрета прерываний не получалось точные временные промежутки выдерживать (для измерения времени использовал счётчик тактов процессора, тогда ещё частота не плавала).
I2C — протокол синхронный, тактовый сигнал передается отдельным проводом. Ему не нужны идеальные тайминги, главное, чтобы не короче возможностей приемника было. Еще, там есть технология clock stretching, позволяющая приемнику самому замедлять передатчик.

А то, что частота процов сейчас плавает, кстати, на rdtsc никак не влияет — поскольку её изначально абьюзили для измерения времени, производителям пришлось делать заплатку, чтобы TSC продолжал измерять время и на современных многоядерных процессорах с плавающей частотой.
+
avatar
+1
Сам сейчас занимаюсь подключением дисплея (у меня TFT IPS) по даташиту, в котором куча ошибок и недоговорённостей. Очень хорошо понимаю эту боль.
Добавлю от себя тот самый плюс.
+
avatar
0
Вопрос по схеме. Зачем два МК?
+
avatar
+6
Шоб былО :)
А серьезно — нужно значительно больше ног, чем есть у ESP32. Народ в аналогичных случаях ставит несколько сдвиговых регистров. Меня больше второй процессор устраивает — гибче получается и при необходимости с минимальное переделкой программы можно использовать там, где не нужен WiFi.
Один процессор с WiFi и много ног дешево и доступно уже не получается.
+
avatar
0
принято.
+
avatar
+2
Алгоритм с многократной перезаписью кадра выглядит убого, если у кто знает, как сделать лучше — пожалуйста, напишите в комментариях.
посмотрите в сторону алгоритма BCM, как раз то что вам нужно. Я как-то было дело работал над оптимизацией вот это либы — ESP32-HUB75-MatrixPanel-DMA.
Довольно интересный проект. Там принцип схожий, динамический диапазон яркости реализуется за счет преобразования веса разрядности цвета в количество повторов свечения пикселей в двоичном коде по степени двойки. У вас можно реализовать похожий алгоритм только наизнанку — взять 3-5 битный серый и чем больше «черноты», тем больше вес BCM.
Кадровый буфер при этом строится в виде связанного списка, что делает ненужным аллокацию больших сплошных блоков памяти и экономит на повторяющихся строках. Вывод там реализован через параллельный i2s dma, но, думаю, вполне можно адаптировать под SPI или RMT при желании. Вообще у есп32 есть неплохие возможности если не полениться покурить IDF. Ну и плат с PSRAM чипом на борту навалом.

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.