k210 C language development-4 read and play fireworks video from sd card

Posted by racer x on Fri, 28 Jan 2022 02:51:28 +0100

k210 C language development-4

Let's start with the results map. I wish you all a happy New Year!

Original video of station B
The day before yesterday, I accidentally saw an activity of CSDN. I could see anything related to fireworks, and then I was going to play a fireworks video with k210. As a result, I found that this activity was to set off fireworks in code, which was irrelevant. It belonged to... Well, record the process.

The general idea is to convert the video file into binary file, put it into SD card, and then read it by MCU and play it with LCD.
The use of k210 has been realized before LCD as well as sd card.
As always, first integrate the required documents:

I found that the original LCD and SD card used the spi0 interface So we need to change the interface in the code.
K210 has FPIOA (field programmable IO array). We can map 255 internal functions to 48 free IOS around the chip. Therefore, we can change the functions of some pins. For example, spi0, which was originally connected to SD card, can now be changed to spi1.

void io_mux_init(void) {
  fpioa_set_function(27, FUNC_SPI1_SCLK);
  fpioa_set_function(26, FUNC_SPI1_D1);
  fpioa_set_function(28, FUNC_SPI1_D0);
  fpioa_set_function(29, FUNC_SPI1_SS3);
}

In addition, the spi0 originally called by these should also be changed to 1

These are all on an sdcard C file, SPI_DEVICE_0 replace all with SPI_ DEVICE_ Just one.
Then test it and it can output normally.
Now it is to first realize a method to convert a picture into a bin file and put it in the sd card, and then read the bin file and display it on LCD.
The picture I used in the test, I think the clear color can make it easier to see some problems

The mold taking software uses Image2Lcd, which has complete functions.
Open the picture, select binary as the output data type, 16 bit true color as the output gray, and then select the output shape according to the screen size. The shape of the input and output image is displayed at the bottom of the software.
The way of scanning is very important. I've done it several times here.
First, I made sure my screen was in dir_ XY_ The input scanning direction in the lrdu direction is as follows:

Therefore, the direction of my image mold should also be in this order. Image2Lcd software displays the scanning mode under the current setting in the upper left

Be careful not to include image header data, which is convenient for us to read.
Use the card reader to put the converted bin file into the SD card.
Use f_read() to read. Under 16 bit true color, each pixel is represented by 2 bytes, so the total number of bytes is 3202402 = 153600.

ret = f_read(&file, (void *)v_buf, 320 * 240 * 2, &v_ret_len);

Then I looked at the LCD display image function in the library and found that it asked me to put a uint32_ Array of type T

void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height,
                      uint32_t *ptr) {
  lcd_set_area(x1, y1, x1 + width - 1, y1 + height - 1);
  tft_write_word(ptr, width * height / 2, lcd_ctl.mode ? 2 : 0);
}

But this small screen only needs uint16 for one pixel_ T is enough.
Then I found out it used a uint32_t to display two pixels. I don't understand why I want to design this way, but I read uint8 directly anyway_ It doesn't matter if t has to be changed.
So now it's time to spell four bytes into a uint32_t to display two pixels.

      for (int n = 0; n < 320 * 240 / 2; n++) {
        img_buf[n] = (v_buf[4 * n] << 24) | (v_buf[4 * n + 1] << 16) |
                     (v_buf[4 * n + 2] << 8) | v_buf[4 * n + 3];
      }

then

lcd_draw_picture(0, 0, 240, 320, img_buf);


This picture is wrong because the scanning direction was not adjusted at that time.
Now more than half of the success has been achieved. In theory, circular playback of pictures is video.
Download the video from station B and up give the link to Baidu online disk in the comment area. If the download speed is too slow, check out the oil monkey plug-in and IDM.
Then there is video conversion and cutting. These online conversion tools are available in Baidu search.
After the whole is like this:

Put this into PotPlayer to get the picture of each frame.
Set to borderless size first

Then select continuous screenshots:

Select the method of screenshot, frame rate


Note that since the picture is obtained by taking a screenshot, it should be borderless and the video should be in the playing state when clicking start.
Then you get a folder with many frame images

Take a picture and show it:

Good, good. Then we use Image2Lcd to take the mold in batch, and the files after taking the mold are placed in the folder of frame images.
After clicking, there are many bin files. We need to combine them into one bin file.
There are many methods. I use the cat instruction of linux.
Under WSL, cd to the bin folder

Just synthesize with bat instruction

Now this vedio The bin file is all the data of this video.
The display of a picture has been realized before, and now it is a for loop

for (uint32_t i = v_fileinfo.fsize / (320 * 240 * 2); i > 0; i--) {
      ret = f_read(&file, (void *)v_buf, 320 * 240 * 2, &v_ret_len);
      if (ret != FR_OK) {
        printf("Read %s err[%d]\n", path, ret);
      } else {
        // printf("Read :> %d %d bytes lenth\n", v_buf, v_ret_len);
      }

      for (int n = 0; n < 320 * 120; n++) {
        img_buf[n] = (v_buf[4 * n] << 24) | (v_buf[4 * n + 1] << 16) |
                     (v_buf[4 * n + 2] << 8) | v_buf[4 * n + 3];
      }

      lcd_draw_picture(0, 0, 240, 320, img_buf);
      // Add address offset
      img_offset += 320 * 240 * 2;
      ret = f_lseek(&file, img_offset);

      if (ret != FR_OK) return -3;
      // printf("%d\n", v_buf[0]);
      // printf("%d\n", v_buf[1]);
      // printf("%d\n", img_buf[0]);
      // printf("%d\n", img_buf[70100]);
    }

be accomplished

Topics: C Single-Chip Microcomputer k210