/**
  ******************************************************************************
  * file           : main.c
  * brief          : Main program body
  *                  Calls target system initialization then loop in main.
  ******************************************************************************
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include <stm32_hal.h>
#include <ux_api.h>
#include <ux_device_class_cdc_acm.h>
//#include <mx_usbx_device_cdc_acm.h>

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private functions prototype -----------------------------------------------*/

extern UX_SLAVE_CLASS_CDC_ACM  *cdc_acm;

// Send data via USB CDC
static void send_CDC(const void *ptr, size_t size) {
    UCHAR *p = (UCHAR *)ptr;
    while (size != 0) {
        ULONG n = 0;
        UINT r = ux_device_class_cdc_acm_write_run(cdc_acm, p, size, &n);
        if (r == UX_STATE_NEXT) {
            p += n;
            size -= n;
            continue;
        } else if (r != UX_STATE_WAIT) {
            break;
        }
        ux_system_tasks_run();
    }
}

// main task
void main_task_run() {
    static enum {OFF, ON} state = OFF;
    static unsigned long int waitSince = 0;

    //Blink the LED and send messages.
    switch (state) {
        case OFF:
            if (HAL_GetTick() - waitSince >= 500) { // in 500ms

                // LED On
                HAL_GPIO_WritePin(LED_PORT,LED_PIN,LED_ACTIVE_STATE);

                waitSince = HAL_GetTick();
                state = ON; // next state
            }
            break;

       case ON:
           if (HAL_GetTick() - waitSince >= 500) { // in 500ms

               // LED OFF
               HAL_GPIO_WritePin(LED_PORT,LED_PIN,LED_INACTIVE_STATE);

               // Send message via USB
               char msg[]="Hallo!\n";
               send_CDC(msg, strlen(msg));

               waitSince = HAL_GetTick();
               state = OFF; // next state
           }
           break;
    }

    // optional: process received data
    /*
    UCHAR buffer[100];
    if (cdc_acm != NULL) {
        ULONG n = 0;
        unsigned r = ux_device_class_cdc_acm_read_run(cdc_acm, buffer, sizeof(buffer), &n);
        if (r == UX_STATE_NEXT) {
            doSomethingWithInput(buf, n);
        }
    }*/
}

/**
  * brief:  The application entry point.
  * retval: none but we specify int to comply with C99 standard
  */
int main(void)
{
  /** System Init: this code placed in targets folder initializes your system.
    * It calls the initialization (and sets the initial configuration) of the peripherals.
    * You can use STM32CubeMX to generate and call this code or not in this project.
    * It also contains the HAL initialization and the initial clock configuration.
    */
  if (mx_system_init() != SYSTEM_OK)
  {
    return (-1);
  }
  else
  {
    /*
      * You can start your application code here
      */
    while (1) {
        ux_device_stack_tasks_run();
        main_task_run();
        ux_system_tasks_run();
    }
  }
} /* end main */

