В целях природы обуздания,
В целях рассеять неученья
Тьму
Берём картину мироздания – да!
И тупо смотрим, что к чему…
// ****************************************************
// 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);
}
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
}
<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);
}
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;
}
}
+19 |
1197
37
|
+125 |
2637
38
|
+42 |
2275
78
|
Лучше напишите конечный ценник на эти игрушки, вкл. все затраты и обслуживание и всё само собой прояснится!
Да, а сама статья про драйвера прекрасна — СПАСИБО ВАМ!
Статья про цифровые ценники лежит в черновиках, будет опубликована в начале следующего месяца. Там будет малая часть информации, в основном с чем я сам игрался.
А что со всем.этим делать — я и сам толком пока не знаю, там более, что у меня их больше полусотни. Бывшие в употреблении можно купить начиная с одного евро — правда, партия в 500 штук :)
Ждем статью про ценники!
С улицы им. генерала Александра Ильича Лизюкова в г. Воронеже же! ;)
Был когда-то там завсегдатаем, но злобные олдфаги постоянно норовили слить карму за безобидные комментарии только потому, что придерживались иного мнения.
P.S.
Для второй ссылки нужен VPN, хотя итак можно догадаться, что там.
Ссылку поменял на другую, вроде должна работать.
А платы вы в чем разводите?
И какой формат видео шел с камеры?
Те кто подключают LCD дисплеи высокого разрешения используют модули с PSRAM
Интересно, ESP32S3 по параллельному интерфейсу будет работать с этим дисплеем?
Идеально подружить это все с Adafruit GFX через Framebuffer. Там всего то нужно свою функцию обновления экрана из FB прикрутить. Тогда и с обновлениями будет полегче
И получают кучу минусов )))
К счастью, там попадаются статьи вроде вашей (правда на 90% переводы), поэтому и есть пока еще что почитать
А во времена WinME я баловался изучением алгоритма работы I2C шины монитора, которая в VGA/DVI кабеле. Через VESA функции BIOS видеокарты находил адреса всех I2C портов, а потом уже из Виндовса, запрещал прерывания и читал/писал в тот порт.
Программ, которые умеют крутить яркость/контрастность и прочее для ЭЛТ мониторов Samsung ещё не было. Была только сервисная программа Samsung, работавшая через специальную LPT-плату. А у меня то же самое через видеокарту получилось! Эх хорошие времена были для программирования.
Разработчики времен MS-DOS читают с недоумением. У них тоже были сегменты по 64К, и жили — не тужили.
Возможно чуть полегче жилось пользователям других расширителей памяти типа DOS4GW, но ни разу не видел, чтоб это использовалось в обычных программах (не играх).
А в WinME + Delphi7 можно было объявлять массивы хоть 10 Мб, и не парится насчёт того, как туда обращаться!
Это 32-битная ось, тут у процесса 4 ГБ виртуального адресного пространства. Естественно, 10 МБ — не вопрос для неё, даже 256 МБ и 1 ГБ (при определенных условиях) можно было выделять непрерывным блоком.
С ESP32 глубоко разбираться лениво, тем более, что там многое не описано, а доступно в виде библиотек. По крайней мере документации с точностью до каждого бита я не видел.
Да и не особо мешает — потеря скорости передачи процент-другой, а на изображение не влияет.
Затык по скорости получается у SPI приемника STM32 — он обрабатывает прерывания и формирует сигналы не так быстро, как хотелось бы. Вот там можно было увеличить скорость уже раза в 2.
я было начал писать статью но забил
Пару лет назад такую писал под Linux. Там, кстати, намного проще доступ до I2C. Даже прерывания отключать не надо.
Чисто интересно: а примерно с какой частотой у вас получилось I2C передачу данных проводить, тем более с параллельно работающими чужими процессами?
DDC вроде как до 400 кГц должен тянуть, а 100 уж точно может. Да там это не так критично.
А то, что частота процов сейчас плавает, кстати, на rdtsc никак не влияет — поскольку её изначально абьюзили для измерения времени, производителям пришлось делать заплатку, чтобы TSC продолжал измерять время и на современных многоядерных процессорах с плавающей частотой.
Добавлю от себя тот самый плюс.
А серьезно — нужно значительно больше ног, чем есть у ESP32. Народ в аналогичных случаях ставит несколько сдвиговых регистров. Меня больше второй процессор устраивает — гибче получается и при необходимости с минимальное переделкой программы можно использовать там, где не нужен WiFi.
Один процессор с WiFi и много ног дешево и доступно уже не получается.
Довольно интересный проект. Там принцип схожий, динамический диапазон яркости реализуется за счет преобразования веса разрядности цвета в количество повторов свечения пикселей в двоичном коде по степени двойки. У вас можно реализовать похожий алгоритм только наизнанку — взять 3-5 битный серый и чем больше «черноты», тем больше вес BCM.
Кадровый буфер при этом строится в виде связанного списка, что делает ненужным аллокацию больших сплошных блоков памяти и экономит на повторяющихся строках. Вывод там реализован через параллельный i2s dma, но, думаю, вполне можно адаптировать под SPI или RMT при желании. Вообще у есп32 есть неплохие возможности если не полениться покурить IDF. Ну и плат с PSRAM чипом на борту навалом.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.