~ruther/stm32h747i-disco-usb-image-viewer

07efcf618615aa92fb78e2b4b9ceb46270523ab4 — Rutherther 3 months ago fb29244
feat: implement application for receiving images
2 files changed, 98 insertions(+), 37 deletions(-)

M src/main.c
M src/usb_device_cdc.c
M src/main.c => src/main.c +86 -32
@@ 239,7 239,7 @@ usb_device_t* init_usb()
  void *usb_dev = usb_device_init(USB_OTG_HS1, &USB_CLASS_CDC_ACM,
                                  0x1234, 0x1111, u"Frantisek Bohacek",
                                  u"Display", 1, NULL);
  cdc_acm_configure(usb_dev, 512);
  cdc_acm_configure(usb_dev, 512 * 4); // 4 full packets maximum
  usb_device_setup(usb_dev);

  return usb_dev;


@@ 337,10 337,13 @@ void init_clock(void) {
  /* clocks_system_clock_source(CLOCK_SOURCE_PLL_1_P_CK, 1, 1, 1, 300); */
}

#define DISPLAY_WIDTH 800
#define DISPLAY_HEIGHT 800

typedef struct {
  uint8_t r;
  uint8_t g;
  uint8_t b;
  uint8_t g;
  uint8_t r;
} pixel_rgb888_t;

pixel_rgb888_t* init_display(display_t* display, fmc_t* fmc)


@@ 360,7 363,7 @@ pixel_rgb888_t* init_display(display_t* display, fmc_t* fmc)

  pin_into_input(&te);

  uint16_t width = 800, height = 480;
  uint16_t width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT;

  // phy = 500 MHz
  uint32_t pix_khz = 62500;


@@ 445,7 448,7 @@ pixel_rgb888_t* init_display(display_t* display, fmc_t* fmc)
  return framebuffer;
}

void app_loop(usb_device_t* usb_dev);
void app_loop(usb_device_t* usb_dev, display_t* display, pixel_rgb888_t* framebuffer);

void main()
{


@@ 472,24 475,10 @@ void main()
  init_button_led();
  pixel_rgb888_t* framebuffer = init_display(&display, &fmc);

  for (uint32_t i = 0; i < 800 * 480; i++) {
    framebuffer[i].r = 0xFF;
    framebuffer[i].g = 0x00;
    framebuffer[i].b = 0x00;
  }

  uint32_t loop = 0;
  while (true) {
    /* display_set_framebuffer(&display, framebuffer); */
    for (uint8_t x = 0; x < 10; x++) {
      framebuffer[loop*10 + x].g = 0xFF;
    }

    display_refresh(&display);
    /* display_reload(&display); */
    delay_ms(500);

    loop++;
  for (uint32_t i = 0; i < DISPLAY_HEIGHT * DISPLAY_WIDTH; i++) {
    framebuffer[i].r = 0;
    framebuffer[i].g = 0;
    framebuffer[i].b = 0;
  }

  // App starts, enable interrupts


@@ 498,25 487,90 @@ void main()
  usb_device_t* usb_dev = init_usb();
  usb_device_wait_for_handshake(usb_dev);

  app_loop(usb_dev);
  app_loop(usb_dev, &display, framebuffer);
}

void app_loop(usb_device_t* usb_dev)
void app_loop(usb_device_t* usb_dev, display_t* display, pixel_rgb888_t* framebuffer)
{
  uint8_t data[64];

  bool handling_cmd = false;
  uint8_t cmd;
  uint32_t pos = 0;

  display_refresh(display);

  while (1) {
    uint16_t received = cdc_data_receive(usb_dev, data, 64);
    uint16_t received = cdc_data_receive(usb_dev, data, 1);

    for (uint16_t i = 0; i < received; i++) {
      data[i] = data[i] + 1;
    if (received == 0) {
      continue;
    }

    if (received > 0) {
      cdc_data_send_blocking(usb_dev, data, received);
    if (!handling_cmd) {
      cmd = data[0];
      pos = 0;
    }

    if (pin_read(&wkup)) {
      cdc_data_send_blocking(usb_dev, (uint8_t*)"Hello world!\r\n", 0);
    switch (cmd) {
    case 'p':
      cdc_data_send_blocking(usb_dev, (uint8_t*)"Pong!\r\n", 0);
      break;
    case 'l':
      pin_toggle(&led1);
      break;
    case 'e':
      handling_cmd = true;

      if (data[0] == 'E') {
        handling_cmd = false;
      }

      cdc_data_send_blocking(usb_dev, data, received);
      break;
    case 'r':
      for (uint32_t i = 0; i < DISPLAY_HEIGHT * DISPLAY_WIDTH; i++) {
        framebuffer[i].r = 0xFF;
        framebuffer[i].g = 0;
        framebuffer[i].b = 0;
      }
      display_refresh(display);
      break;
    case 'g':
      for (uint32_t i = 0; i < DISPLAY_HEIGHT * DISPLAY_WIDTH; i++) {
        framebuffer[i].r = 0;
        framebuffer[i].g = 0xFF;
        framebuffer[i].b = 0;
      }
      display_refresh(display);
      break;
    case 'b':
      for (uint32_t i = 0; i < DISPLAY_HEIGHT * DISPLAY_WIDTH; i++) {
        framebuffer[i].r = 0;
        framebuffer[i].g = 0;
        framebuffer[i].b = 0xFF;
      }
      display_refresh(display);
      break;
    case 'B':
      for (uint32_t i = 0; i < DISPLAY_HEIGHT * DISPLAY_WIDTH; i++) {
        framebuffer[i].r = 0;
        framebuffer[i].g = 0;
        framebuffer[i].b = 0;
      }
      display_refresh(display);
      break;
    case 'i':
      handling_cmd = true;
      ((uint8_t *)framebuffer)[pos] = data[0];

      pos++;

      if (pos == DISPLAY_WIDTH * DISPLAY_HEIGHT * 3) {
        handling_cmd = false;
        display_refresh(display);
      }
      break;
    }
  }
}

M src/usb_device_cdc.c => src/usb_device_cdc.c +12 -5
@@ 586,11 586,13 @@ void usb_device_cdc_received_data_callback(usb_device_t *device, packet_info_t *
      queue_enqueue(cdc->rx_buffer, (void*)&data[i]);
    }

    reg_write_bits_pos(&device->out[2].DOEPTSIZ, MAX_PACKET_SIZE, USB_OTG_DOEPTSIZ_XFRSIZ_Pos, 0xFFFF);
    reg_write_bits_pos(&device->out[2].DOEPTSIZ, 1, USB_OTG_DOEPTSIZ_PKTCNT_Pos, 0x3FF);
    device->out[DATA_ENDPOINT].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
    if (queue_space(cdc->rx_buffer) >= MAX_PACKET_SIZE) {
      reg_write_bits_pos(&device->out[2].DOEPTSIZ, MAX_PACKET_SIZE, USB_OTG_DOEPTSIZ_XFRSIZ_Pos, 0xFFFF);
      reg_write_bits_pos(&device->out[2].DOEPTSIZ, 1, USB_OTG_DOEPTSIZ_PKTCNT_Pos, 0x3FF);
      device->out[DATA_ENDPOINT].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
    }
  } else if(packet->packet_status == PACKET_OUT_TRANSFER_COMPLETED) {
      if (queue_space(cdc->rx_buffer)) {
      if (queue_space(cdc->rx_buffer) >= MAX_PACKET_SIZE) {
        reg_write_bits_pos(&device->out[2].DOEPTSIZ, MAX_PACKET_SIZE, USB_OTG_DOEPTSIZ_XFRSIZ_Pos, 0xFFFF);
        reg_write_bits_pos(&device->out[2].DOEPTSIZ, 1, USB_OTG_DOEPTSIZ_PKTCNT_Pos, 0x3FF);
        device->out[DATA_ENDPOINT].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;


@@ 601,7 603,12 @@ void usb_device_cdc_received_data_callback(usb_device_t *device, packet_info_t *
}

void usb_device_cdc_nak_callback(usb_device_t *device, uint8_t endpoint) {
  // Nothing to do for now
  usb_device_cdc_t* cdc = (usb_device_cdc_t*)device->class;
  if (queue_space(cdc->rx_buffer) >= MAX_PACKET_SIZE) {
    reg_write_bits_pos(&device->out[2].DOEPTSIZ, MAX_PACKET_SIZE, USB_OTG_DOEPTSIZ_XFRSIZ_Pos, 0xFFFF);
    reg_write_bits_pos(&device->out[2].DOEPTSIZ, 1, USB_OTG_DOEPTSIZ_PKTCNT_Pos, 0x3FF);
    device->out[DATA_ENDPOINT].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
  }
}
void usb_device_cdc_nyet_callback(usb_device_t *device, uint8_t endpoint) {
  // Nothing to do for now

Do not follow this link