Перейти к содержанию
    

должны быть, но не обязаны. Я глянул даташит на V3s что у меня есть (на английском), там расписаны времянки, но самих стробов CS, WR, адресные биты A* на выводах микроконтроллера НЕ нашёл. Таблицы мультиплексирования выводов тоже молчат.

Просто приводят картинку с времянками, которая как бы намекает, что без дополнительной логики (ПЛИС, ЦПЛД,рассыпуха) не обойтись:

картинка намекает ровно на обратное.

а регистры для доступа к шине, конфигурирования интерфейса, отдельные регистры для чтения/записи по двум отдельным адресам через A1 сделали видимо просто так, да ещё и ноги наружу вывести забыли.

таблицы мультиплексирования выводов молчат, так как там либо TCON включается либо нет, а как он уже внутри себя будет свои ноги использовать gpio конечно не знает.

подключение LCD с i80 к А20

post-3954-1522343656_thumb.png

из китайского официального мануала про lcd, для v3s ещё видимо не запилили, но не думаю что периферийные блоки хоть чем-то отличаются, в даташите там всё тоже самое.

а почему линии данных так перекошены - не знаю, в китайском не силён.

 

Был один головняк(SDRAM), будет два (преобразователь SDIO в i8080 для LCD :) )

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

_pv, большое спасибо! :rolleyes: Вот как раз этой схемы мне не хватало, а я уже хотел логику прикидывать к CLK, LCDDE, чтобы выдать нужную полярность по стробам.

Зарегался на том форуме и поинтересовался у китайцев - сказали, что всё как в A10, дали инфу по подключению и даташиты:

https://debugdump.com/t_900.html

Что понравилось - отвечают очень оперативно, возможно они контачат с Alwinner напрямую.

Таблица подключения от A10 по назначению пинов совпадает с вашей картинкой:

post-99126-1522368108_thumb.png

 

Очень надеюсь, что в v3s работа с дисплеем в режиме i8080 присутствует и её алгоритм аналогичен как в A20, A10.

 

Почему я не хочу подключать дисплей по параллельному RGB? Потому что контроллер будет постоянно вынужден как угорелый рисовать кадр, в то время как он ещё будет не готов, а это несколько неудобно! Плюс отсутствие режимов LCD с выбором прямоугольника отрисовки, направлений - проще через встроенный контроллер дисплея это делать. Ну и как правило, большинство LCD матриц помимо простого RGB содержат ещё I2C/SPI порт для конфигурации. Так что в плане переносимости мне проще через i8080-BUS работать.

 

Этот Alwinner полон загадок, заманчив высокой тактовой 1,2 ГГц + DDR 400 МГц, QFP корпусом и встроенной памятью. Но его загадочность меня настораживает :)

Надо сообразить простейшую плату для опытов (v3s есть на руках), для питания пока поставлю обычнее LDO на 3.3V, 3V, 1.2V и 1.8V (точно в даташите смотреть надо).

Наподобие как STM-NUCLEO - по минимуму обвязки: питание, кварц, пины на порты, MCU, SD карта памяти для загрузки.

 

Конечно, после мигания светодиодами и ком-порта, прийдётся ковырять Linux BSP, что наверно трудоемко.

 

А обращаться к дисплею в режиме 8080 как? (команды и данные слать) . Через TCON0_CPU_WR_REG, TCON0_CPU_RD0_REG и TCON0_CPU_RD1_REG ? Команда или данные выбираются через бит 25 регистра TCON0_CPU_IF_REG ? (управление A1).

 

На первых порах конечно, линию DC LCD можно посадить на обычный GPIO без ущерба скорости, но хочется чтобы красиво было.

 

картинка намекает ровно на обратное.

а регистры для доступа к шине, конфигурирования интерфейса, отдельные регистры для чтения/записи по двум отдельным адресам через A1 сделали видимо просто так, да ещё и ноги наружу вывести забыли.

таблицы мультиплексирования выводов молчат, так как там либо TCON включается либо нет, а как он уже внутри себя будет свои ноги использовать gpio конечно не знает.

подключение LCD с i80 к А20

post-3954-1522343656_thumb.png

из китайского официального мануала про lcd, для v3s ещё видимо не запилили, но не думаю что периферийные блоки хоть чем-то отличаются, в даташите там всё тоже самое.

а почему линии данных так перекошены - не знаю, в китайском не силён.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поковырял немножко Linux BSP, "linux-master".

Вырисовываются интересные вещи касаемо работы LCD в i8080 bus mode.

 

__s32 LCD_CPU_WR(__u32 screen_id,__u32 index,__u32 data)
{
    tcon0_cpu_wr_16b(screen_id,index,data);
    return 0;
}

__s32 LCD_CPU_WR_INDEX(__u32 screen_id,__u32 index)
{
    tcon0_cpu_wr_16b_index(screen_id,index);
    return 0;
}

__s32 LCD_CPU_WR_DATA(__u32 screen_id,__u32 data)
{
    tcon0_cpu_wr_16b_data(screen_id,data);
    return 0;
}

 

Пошёл дальше:

 

s32 tcon0_cpu_wr_16b(u32 sel, u32 index, u32 data)
{
    tcon0_cpu_wr_24b(sel,tcon0_cpu_16b_to_24b(index),tcon0_cpu_16b_to_24b(data));
    return 0;
}

u32 tcon0_cpu_16b_to_24b(u32 value)
{
    return
          ((value & 0xfc00)<<8)
        | ((value & 0x0300)<<6)
        | ((value & 0x00e0)<<5)
        | ((value & 0x001f)<<3);
}

s32 tcon0_cpu_wr_24b(u32 sel, u32 index, u32 data)
{
    tcon0_cpu_wr_24b_index(sel,index);
    tcon0_cpu_wr_24b_data(sel,data);
    return 0;
}

s32 tcon0_cpu_wr_24b_index(u32 sel, u32 index)
{
    u32 count = 0;
    while((tcon0_cpu_busy(sel)) && (count < 50)) {
        count ++;
        disp_delay_us(100);
    }
    lcd_dev[sel]->tcon0_cpu_ctl.bits.ca = 0;
    lcd_dev[sel]->tcon0_cpu_wr.bits.data_wr = index;
    return 0;
}

s32 tcon0_cpu_wr_24b_data(u32 sel, u32 data)
{
    u32 count = 0;
    while((tcon0_cpu_busy(sel)) && (count < 50)) {
        count ++;
        disp_delay_us(100);
    }
    lcd_dev[sel]->tcon0_cpu_ctl.bits.ca = 1;        //tcon0_cpu_if_reg_t
    lcd_dev[sel]->tcon0_cpu_wr.bits.data_wr = data; //tcon0_cpu_wr_reg_t
    return 0;
}

 

Тут мы видим, что перед посылкой байтов команды или данных - цикл с ожиданием пока устройство занято. Это очень плохо!

Все параллельные шины с которыми приходилось работать - EBI у AT91RM9200, FSMC у STM32, FBI у Блекфина - не имели костыля для ожидания завершения.

 

Сама процедура ожидания:

 

u32 tcon0_cpu_busy(u32 sel)
{
    if(lcd_dev[sel]->tcon0_cpu_ctl.bits.wr_flag
        || lcd_dev[sel]->tcon0_cpu_ctl.bits.rd_flag)
        return 1;
    else
        return 0;
}

 

 

Ну и интуитивно понятно, что структуры как раз описывают биты и смещения регистров от базового адреса.

 

Как всё сложно описано!!! И всё для того чтобы послать на шину 8080 байт данных!!!

 

Чего стоят только описания структур и юнионов:

 

static volatile __de_lcd_dev_t *lcd_dev[2];

s32 tcon_set_reg_base(u32 sel, u32 base)
{
    lcd_dev[sel]=(__de_lcd_dev_t *)base;
    return 0;
}


tcon_set_reg_base(screen_id,para->reg_base[DISP_MOD_LCD0]);
tcon_set_reg_base(screen_id,para->reg_base[DISP_MOD_LCD1]);

typedef struct
{
    u32                   reg_base[DISP_MOD_NUM];
    u32                   reg_size[DISP_MOD_NUM];
    u32                   irq_no[DISP_MOD_NUM];

    s32 (*disp_int_process)(u32 sel);
    s32 (*vsync_event)(u32 sel);
    s32 (*start_process)(void);
    s32 (*capture_event)(u32 sel);
    s32 (*shadow_protect)(u32 sel, bool protect);
    disp_sw_init_para *sw_init_para;
}__disp_bsp_init_para;



//device define
typedef struct
{
    tcon_gctl_reg_t                tcon_gctl;                //0x000
    tcon_gint0_reg_t            tcon_gint0;                //0x004
    tcon_gint1_reg_t            tcon_gint1;                //0x008
    tcon_reservd_reg_t            tcon_reg00c;            //0x00c
    tcon0_frm_ctl_reg_t            tcon0_frm_ctl;            //0x010
    tcon0_frm_seed_reg_t        tcon0_frm_seed_pr;        //0x014
    tcon0_frm_seed_reg_t        tcon0_frm_seed_pg;        //0x018
    tcon0_frm_seed_reg_t        tcon0_frm_seed_pb;        //0x01c
    tcon0_frm_seed_reg_t        tcon0_frm_seed_lr;        //0x020
    tcon0_frm_seed_reg_t        tcon0_frm_seed_lg;        //0x024
    tcon0_frm_seed_reg_t        tcon0_frm_seed_lb;        //0x028
    tcon0_frm_tab_reg_t            tcon0_frm_tbl_0;        //0x02c
    tcon0_frm_tab_reg_t            tcon0_frm_tbl_1;        //0x030
    tcon0_frm_tab_reg_t            tcon0_frm_tbl_2;        //0x034
    tcon0_frm_tab_reg_t            tcon0_frm_tbl_3;        //0x038
    tcon_reservd_reg_t            tcon_reg03c;            //0x03c
    tcon0_ctl_reg_t                tcon0_ctl;                //0x040
    tcon0_dclk_reg_t            tcon0_dclk;                //0x044
    tcon0_basic0_reg_t            tcon0_basic0;            //0x048
    tcon0_basic1_reg_t            tcon0_basic1;            //0x04c
    tcon0_basic2_reg_t            tcon0_basic2;            //0x050
    tcon0_basic3_reg_t            tcon0_basic3;            //0x054
    tcon0_hv_if_reg_t            tcon0_hv_ctl;            //0x058
    tcon_reservd_reg_t            tcon_reg05c;            //0x05c
    tcon0_cpu_if_reg_t            tcon0_cpu_ctl;            //0x060
    tcon0_cpu_wr_reg_t            tcon0_cpu_wr;            //0x064
    tcon0_cpu_rd0_reg_t            tcon0_cpu_rd;            //0x068
    tcon0_cpu_rd1_reg_t            tcon0_cpu_fet;            //0x06c
    tcon_reservd_reg_t            tcon_reg070[6];            //0x070~0x84
    tcon0_io_pol_reg_t            tcon0_io_pol;            //0x088
    tcon0_io_tri_reg_t            tcon0_io_tri;            //0x08c
    tcon1_ctl_reg_t                tcon1_ctl;                //0x090
    tcon1_basic0_reg_t            tcon1_basic0;            //0x094
    tcon1_basic1_reg_t            tcon1_basic1;            //0x098
    tcon1_basic2_reg_t            tcon1_basic2;            //0x09c
    tcon1_basic3_reg_t            tcon1_basic3;            //0x0a0
    tcon1_basic4_reg_t            tcon1_basic4;            //0x0a4
    tcon1_basic5_reg_t            tcon1_basic5;            //0x0a8
    tcon_reservd_reg_t            tcon_reg0ac;            //0x0ac
    tcon1_ps_sync_reg_t            tcon1_ps_ctl;            //0x0b0
    tcon_reservd_reg_t            tcon_reg0b4[15];        //0x0b4~0x0ec
    tcon1_io_pol_reg_t            tcon1_io_pol;            //0x0f0
    tcon1_io_tri_reg_t            tcon1_io_tri;            //0x0f4
    tcon_ecc_fifo_reg_t            tcon_ecfifo_ctl;        //0x0f8
    tcon_debug_reg_t            tcon_debug;                //0x0fc
    tcon_ceu_ctl_reg_t            tcon_ceu_ctl;            //0x110
    tcon_reservd_reg_t            tcon_reg104[3];            //0x104~0x10c
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_rr;        //0x110
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_rg;        //0x114
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_rb;        //0x118
    tcon_ceu_coef_add_reg_t        tcon_ceu_coef_rc;        //0x11c
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_gr;        //0x120
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_gg;        //0x124
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_gb;        //0x128
    tcon_ceu_coef_add_reg_t        tcon_ceu_coef_gc;        //0x12c
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_br;        //0x130
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_bg;        //0x134
    tcon_ceu_coef_mul_reg_t        tcon_ceu_coef_bb;        //0x138
    tcon_ceu_coef_add_reg_t        tcon_ceu_coef_bc;        //0x13c
    tcon_ceu_coef_rang_reg_t    tcon_ceu_coef_rv;        //0x140
    tcon_ceu_coef_rang_reg_t    tcon_ceu_coef_gv;        //0x144
    tcon_ceu_coef_rang_reg_t    tcon_ceu_coef_bv;        //0x148
    tcon_reservd_reg_t            tcon_reg14c[5];            //0x14c~0x15c
    tcon0_cpu_tri0_reg_t        tcon0_cpu_tri0;            //0x160
    tcon0_cpu_tri1_reg_t        tcon0_cpu_tri1;            //0x164
    tcon0_cpu_tri2_reg_t        tcon0_cpu_tri2;            //0x168
    tcon0_cpu_tri3_reg_t        tcon0_cpu_tri3;            //0x16c
    tcon0_cpu_tri4_reg_t        tcon0_cpu_tri4;            //0x170
    tcon0_cpu_tri5_reg_t        tcon0_cpu_tri5;            //0x174
    tcon_reservd_reg_t            tcon_reg178[2];            //0x178~0x17c
    tcon_cmap_ctl_reg_t            tcon_cmap_ctl;            //0x180
    tcon_reservd_reg_t            tcon_reg184[3];            //0x184~0x18c
    tcon_cmap_odd0_reg_t        tcon_cmap_odd0;            //0x190
    tcon_cmap_odd1_reg_t        tcon_cmap_odd1;            //0x194
    tcon_cmap_even0_reg_t        tcon_cmap_even0;        //0x198
    tcon_cmap_even1_reg_t        tcon_cmap_even1;        //0x19c
    tcon_reservd_reg_t            tcon_reg1a0[20];        //0x1a0~0x1ec
    tcon_safe_period_reg_t        tcon_volume_ctl;        //0x1f0
    tcon_reservd_reg_t            tcon_reg1f4[3];            //0x1f4~0x1fc
    tcon_mux_ctl_reg_t            tcon_mul_ctl;            //0x200
    tcon_reservd_reg_t            tcon_reg204[9];            //0x204~0x224
    tcon_reservd_reg_t            tcon_reg228[54];        //0x228~0x2fc
    tcon1_fill_ctl_reg_t        tcon_fill_ctl;            //0x300
    tcon1_fill_begin_reg_t        tcon_fill_start0;        //0x304
    tcon1_fill_end_reg_t        tcon_fill_end0;            //0x308
    tcon1_fill_data_reg_t        tcon_fill_data0;        //0x30c
    tcon1_fill_begin_reg_t        tcon_fill_start1;        //0x310
    tcon1_fill_end_reg_t        tcon_fill_end1;            //0x314
    tcon1_fill_data_reg_t        tcon_fill_data1;        //0x318
    tcon1_fill_begin_reg_t        tcon_fill_start2;        //0x31c
    tcon1_fill_end_reg_t        tcon_fill_end2;            //0x320
    tcon1_fill_data_reg_t        tcon_fill_data2;        //0x324
    tcon_reservd_reg_t            tcon_reg328[54];        //0x328~0x3fc
    tcon_gamma_tlb_reg_t        tcon_gamma_tlb[256];    //0x400
}__de_lcd_dev_t;

typedef union
{
    u32 dwval;
    struct
    {
        u32 trigger_en                 :  1;    // default: 0;
        u32 trigger_start              :  1;    // default: 0;
        u32 trigger_fifo_en            :  1;    // default: 0;
        u32 trigger_fifo_bist_en       :  1;    // default: 0;
        u32 trigger_sync_mode          :  2;    // default: 0;
        u32 res0                       : 10;    // default:;
        u32 flush                      :  1;    // default: 0;
        u32 auto_                       :  1;    // default: 0;
        u32 res1                       :  4;    // default:;
        u32 rd_flag                    :  1;    // default: 0;
        u32 wr_flag                    :  1;    // default: 0;
        u32 vsync_cs_sel               :  1;    // default: 0;
        u32 ca                         :  1;    // default: 0;
        u32 da                         :  1;    // default: 0;
        u32 res2                       :  1;    // default:;
        u32 cpu_mode                    :  4;    // default: 0;
    } bits;
} tcon0_cpu_if_reg_t;

typedef union
{
    u32 dwval;
    struct
    {
        u32 data_wr                    : 24;    // default: 0;
        u32 res0                       :  8;    // default:;
    } bits;
} tcon0_cpu_wr_reg_t;

 

Предстоит жёсткий секс с Линуксом :)

 

Начну-ка я наверно с A13, отладочной платы Olinuxino (тоже есть на руках).

 

Чем-то напомнило индусский код :) Теперь надеюсь, вы поняли, почему я не люблю писать под линукс? Потому что громоздко и тормозит! Нужен чистый поток сознания в программировании!

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что-то всё действительно загадочно, есть регистр tcon0_cpu_wr_reg у которого по даташиту 24 разряда и который при записи должен писать целиком в LCD_D[23:0],

а потом взяли и как попало подключили линии данных, не подряд, а старшие шесть разрядов каждого цвета (ну чтобы 24х разрядный цвет преобразовывать в 666, или 565 схемотехнически), а теперь руками каждый пиксель перепаковываем обратно из 16/18 в 24,

а нельзя было просто подключить шину подряд, LCD_D[15:0] или [17:0], и писать данные как есть, раз они уже изначально в таком формате?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что-то всё действительно загадочно, есть регистр tcon0_cpu_wr_reg у которого по даташиту 24 разряда и который при записи должен писать целиком в LCD_D[23:0],

а потом взяли и как попало подключили линии данных, не подряд, а старшие шесть разрядов каждого цвета (ну чтобы 24х разрядный цвет преобразовывать в 666, или 565 схемотехнически), а теперь руками каждый пиксель перепаковываем обратно из 16/18 в 24,

а нельзя было просто подключить шину подряд, LCD_D[15:0] или [17:0], и писать данные как есть, раз они уже изначально в таком формате?

Я бы отталкивался от того, по каким линиям пойдут биты байта при записи в регистр tcon0_cpu_wr_reg. Проверить в принципе это можно, просто зациклив передачу в этот регистр и путём вызванивания тестером логического уровня на каждом бите. Увы и ах - осциллографа и логического анализатора под рукой нет. :(

 

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

 

Должно хватить вот этого(код я писал):

 

#define CA 25 /* A1位 A1 bit */

#define TCON 0x01C0C000 /* TCON基地址 TCON Base Address */

#define TCON0_CPU_IF_REG *(volatile u32*)(TCON+0x60)
#define TCON0_CPU_WR_REG *(volatile u32*)(TCON+0x64)

void TCON0_INDEX(u32 index)
{
TCON0_CPU_IF_REG&=~(1UL<<CA); //清除CA位 clear CA bit
TCON0_CPU_WR_REG=index;       //写索引 write index
}

void TCON0_DATA(u32 data)
{
TCON0_CPU_IF_REG|=(1UL<<CA);   //设置CA位 set CA bit
TCON0_CPU_WR_REG=data;         // 写入数据 write data
}

 

Не забыв отремапить ноги GPIO и включив тактирование нужных узлов периферии.

 

и отынитить TCON для режима CPU I/F i8080 :)

 

Ну и второй головняк - тайминги шины. Подозреваю, что на ширину строба записи будет влиять делитель для DCLK, а на длительность цикла - длина VSYNC лили LCDDE

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...