README.md

K1948BK018_ST7735s_160x80_SPI0_DMA_ROM_RAM

Развитие предыдущего моего проекта «K1948BK018_ST7735s_160x80_SPI0_DMA_512»

Цель

Выводить попеременно два изображения 160 x 80 x 5R6G5B на дисплей посредством DMA и SPI двумя способами:


1) Непосредственно из ПЗУ, отдавая управление передачей DMA-каналу № 0 и заканчивая выполнение метода:

void ST7735s_class::draw_DMA_ROM/* ПЗУ */(u16 const* picture)
{
    command4(/* CASET */0x2A, 0, yoff, 0, yoff + ysize - 1);
    command4(/* RASET */0x2B, 0, xoff, 0, xoff + xsize - 1);
    command (/* RAMWR */0x2C);
    HAL_SPI_Disable ( &h_spi ) ;
    HAL_SPI_Enable  ( &h_spi ) ;
    HAL_DMA_Start ( &h_dma_ch0,
                    (void*)&picture[2],
                    (void*)&h_spi.Instance->TXDATA,
                    xsize * ysize * sizeof(u16) - 1 ) ;
}

2) Порциями по пол-килобайта через ОЗУ-буфер:

void ST7735s_class::draw_DMA_RAM/* ОЗУ */(uint16_t const* picture)
{
    command4(/* CASET */0x2A, 0, yoff, 0, yoff + ysize - 1);
    command4(/* RASET */0x2B, 0, xoff, 0, xoff + xsize - 1);
    command (/* RAMWR */0x2C);
    uint32_t const* p = (uint32_t const*)&picture[2];
    static constexpr uint32_t N = 256/* пикселей = пол-кило-байтов */;
    uint32_t size = xsize * ysize / N ; /// количество порций величиной в N * sizeof(uint16_t)
    while ( size-- )
    {
        uint32_t t [ N/2 ] ; for ( uint32_t i = 0; i < N/2; i++ ) t[i] = p[i] ;
        HAL_SPI_Enable  ( &h_spi ) ;
            HAL_DMA_Start ( &h_dma_ch0, (void*)t, (void*)&h_spi.Instance->TXDATA, N * sizeof(uint16_t) /* байтов */ - 1 ) ;
            volatile uint32_t i = 0; while ( i < 1400 ) i++; /// НЕОБХОДИМАЯ ПАУЗА, ПОТОМУ ЧТО <<HAL_DMA_Wait ...>> ЗДЕСЬ НЕ РАБОТАЕТ (???)
            /// HAL_DMA_Wait ( &h_dma_ch0, /* DMA_TIMEOUT_DEFAULT */ 3E6 ) <--- здесь не работает почему-то !
            /// while ( ! HAL_DMA_GetChannelReadyStatus(&h_dma_ch0) ) <--- здесь не работает почему-то !
        HAL_SPI_Disable ( &h_spi ) ;
        p += N/2;
    }
}

(см. «terminal_2M_baud__ST7735s_SPI_DMA_RAM.jpg»)


Важное замечание

Если в методе записи байта в дисплей:

void ST7735s_class::data(u8 d)
{
    /// HAL_SPI_Exchange(&h_spi, (u8*)&d, 0, sizeof(u8), SPI_TIMEOUT_DEFAULT) <--- нельзя здесь вызывать, если мы используем DMA (*)
    HAL_SPI_Enable  ( &h_spi ) ;
        HAL_DMA_Start ( &h_dma_ch0, (void*)&d, (void*)&h_spi.Instance->TXDATA, 0/* всего один байт */ ) ;
        if ( HAL_DMA_Wait  ( &h_dma_ch0, DMA_TIMEOUT_DEFAULT ) != HAL_OK ) xprintf ( "DMA timeout\r\n" ) ;
    HAL_SPI_Disable ( &h_spi ) ;
}

вернуть вызов “HAL_SPI_Exchange” (*) и удалить использование DMA, что несомненно облегчило БЫ код, то изображение перестанет периодически выводиться. Пока мне не ясно почему.


Смотрите видео: https://youtu.be/GFPKr-7k9Kw


Среда разработки: GCC-RISC-V-v12.2.1


Описание

Вывод изображения на дисплей с помощью SPI & DMA из ПЗУ & ОЗУ-буфера. Учёт некоторых особенностей работы с DMA (ПДП) на МК к1948вк018

Конвейеры
0 успешных
0 с ошибкой