video_player_hal.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "video_player_hal.h"
  2. #include "video_player.h"
  3. void video_player_dma_isr(void* context) {
  4. VideoPlayerApp* player = (VideoPlayerApp*)context;
  5. // half of transfer
  6. if(LL_DMA_IsActiveFlag_HT1(DMA1)) {
  7. LL_DMA_ClearFlag_HT1(DMA1);
  8. // fill first half of the buffer
  9. //uint8_t* audio_buffer = player->audio_buffer;
  10. //stream_read(player->stream, player->image_buffer, player->image_buffer_length);
  11. //stream_read(player->stream, audio_buffer, player->audio_chunk_size);
  12. static VideoPlayerEvent event = {.type = EventType1stHalf};
  13. furi_message_queue_put(player->event_queue, &event, 0);
  14. }
  15. // transfer complete
  16. if(LL_DMA_IsActiveFlag_TC1(DMA1)) {
  17. LL_DMA_ClearFlag_TC1(DMA1);
  18. // fill second half of buffer
  19. //uint8_t* audio_buffer = &player->audio_buffer[player->audio_chunk_size];
  20. //stream_read(player->stream, player->image_buffer, player->image_buffer_length);
  21. //stream_read(player->stream, audio_buffer, player->audio_chunk_size);
  22. static VideoPlayerEvent event = {.type = EventType2ndHalf};
  23. furi_message_queue_put(player->event_queue, &event, 0);
  24. }
  25. }
  26. void player_init_hardware_and_play(VideoPlayerApp* player) {
  27. //DMA:
  28. uint32_t address = (uint32_t)player->audio_buffer;
  29. uint32_t size = player->audio_chunk_size * 2;
  30. uint32_t dma_dst = (uint32_t) & (SPEAKER_PWM_TIMER->CCR1);
  31. LL_DMA_ConfigAddresses(DMA_INSTANCE, address, dma_dst, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
  32. LL_DMA_SetDataLength(DMA_INSTANCE, size);
  33. LL_DMA_SetPeriphRequest(DMA_INSTANCE, LL_DMAMUX_REQ_TIM1_UP);
  34. LL_DMA_SetDataTransferDirection(DMA_INSTANCE, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
  35. LL_DMA_SetChannelPriorityLevel(DMA_INSTANCE, LL_DMA_PRIORITY_VERYHIGH);
  36. LL_DMA_SetMode(DMA_INSTANCE, LL_DMA_MODE_CIRCULAR);
  37. LL_DMA_SetPeriphIncMode(DMA_INSTANCE, LL_DMA_PERIPH_NOINCREMENT);
  38. LL_DMA_SetMemoryIncMode(DMA_INSTANCE, LL_DMA_MEMORY_INCREMENT);
  39. LL_DMA_SetPeriphSize(DMA_INSTANCE, LL_DMA_PDATAALIGN_HALFWORD);
  40. LL_DMA_SetMemorySize(DMA_INSTANCE, LL_DMA_PDATAALIGN_HALFWORD);
  41. LL_DMA_EnableIT_TC(DMA_INSTANCE);
  42. LL_DMA_EnableIT_HT(DMA_INSTANCE);
  43. // ==== TIMERS:
  44. furi_hal_bus_enable(FuriHalBusTIM1);
  45. LL_TIM_InitTypeDef TIM_InitStruct = {0};
  46. LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
  47. TIM_InitStruct.Prescaler = 1;
  48. TIM_InitStruct.Autoreload = 255;
  49. TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  50. LL_TIM_Init(SPEAKER_PWM_TIMER, &TIM_InitStruct);
  51. TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
  52. TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
  53. TIM_OC_InitStruct.CompareValue = 0;
  54. LL_TIM_OC_Init(SPEAKER_PWM_TIMER, SPEAKER_PWM_TIMER_CHANNEL, &TIM_OC_InitStruct);
  55. LL_TIM_EnableAllOutputs(SPEAKER_PWM_TIMER);
  56. LL_TIM_EnableCounter(SPEAKER_PWM_TIMER);
  57. //SAMPLE RATE TIMER:
  58. LL_TIM_InitTypeDef TIM_InitStruct1 = {0};
  59. LL_TIM_OC_InitTypeDef TIM_OC_InitStruct1 = {0};
  60. TIM_InitStruct1.Prescaler = 0;
  61. TIM_InitStruct1.Autoreload =
  62. (TIMER_BASE_CLOCK / (uint32_t)player->sample_rate - 1); // to support various sample rates
  63. TIM_InitStruct1.CounterMode = LL_TIM_COUNTERMODE_UP;
  64. LL_TIM_Init(SAMPLE_RATE_TIMER, &TIM_InitStruct1);
  65. TIM_OC_InitStruct1.OCMode = LL_TIM_OCMODE_PWM1;
  66. TIM_OC_InitStruct1.OCState = LL_TIM_OCSTATE_ENABLE;
  67. LL_TIM_OC_Init(SAMPLE_RATE_TIMER, SPEAKER_PWM_TIMER_CHANNEL, &TIM_OC_InitStruct1);
  68. LL_TIM_EnableAllOutputs(SAMPLE_RATE_TIMER);
  69. SAMPLE_RATE_TIMER->CNT = 0;
  70. furi_hal_gpio_init_ex(
  71. &gpio_ext_pa6, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16);
  72. /*if(!(furi_hal_speaker_is_mine()))
  73. {
  74. bool unu = furi_hal_speaker_acquire(1000);
  75. UNUSED(unu);
  76. }*/
  77. furi_hal_interrupt_set_isr_ex(FuriHalInterruptIdDma1Ch1, 15, video_player_dma_isr, player);
  78. // START!!
  79. LL_TIM_EnableDMAReq_UPDATE(SAMPLE_RATE_TIMER);
  80. LL_DMA_EnableChannel(DMA_INSTANCE);
  81. LL_TIM_EnableCounter(SAMPLE_RATE_TIMER);
  82. }
  83. void player_deinit_hardware() {
  84. LL_DMA_DisableChannel(DMA_INSTANCE);
  85. if(furi_hal_speaker_is_mine()) {
  86. furi_hal_speaker_release();
  87. }
  88. furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
  89. furi_hal_interrupt_set_isr_ex(FuriHalInterruptIdDma1Ch1, 15, NULL, NULL);
  90. if(furi_hal_bus_is_enabled(FuriHalBusTIM1)) {
  91. furi_hal_bus_disable(FuriHalBusTIM1);
  92. }
  93. }
  94. void player_stop() {
  95. LL_TIM_DisableCounter(SAMPLE_RATE_TIMER);
  96. }
  97. void player_start() {
  98. LL_TIM_EnableCounter(SAMPLE_RATE_TIMER);
  99. }