Subversion Repositories FuelGauge

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 6
Line 236... Line 236...
236
                      ##### IO operation functions #####
236
                      ##### IO operation functions #####
237
 ===============================================================================
237
 ===============================================================================
238
    This subsection provides a set of Wakeup and FIFO mode related callback functions.
238
    This subsection provides a set of Wakeup and FIFO mode related callback functions.
239
 
239
 
240
#if defined(USART_CR1_UESM)
240
#if defined(USART_CR1_UESM)
-
 
241
#if defined(USART_CR3_WUFIE)
241
    (#) Wakeup from Stop mode Callback:
242
    (#) Wakeup from Stop mode Callback:
242
        (+) HAL_UARTEx_WakeupCallback()
243
        (+) HAL_UARTEx_WakeupCallback()
243
 
244
 
244
#endif
245
#endif
-
 
246
#endif
245
@endverbatim
247
@endverbatim
246
  * @{
248
  * @{
247
  */
249
  */
248
 
250
 
249
#if defined(USART_CR1_UESM)
251
#if defined(USART_CR1_UESM)
-
 
252
#if defined(USART_CR3_WUFIE)
250
/**
253
/**
251
  * @brief UART wakeup from Stop mode callback.
254
  * @brief UART wakeup from Stop mode callback.
252
  * @param huart UART handle.
255
  * @param huart UART handle.
253
  * @retval None
256
  * @retval None
254
  */
257
  */
Line 260... Line 263...
260
  /* NOTE : This function should not be modified, when the callback is needed,
263
  /* NOTE : This function should not be modified, when the callback is needed,
261
            the HAL_UARTEx_WakeupCallback can be implemented in the user file.
264
            the HAL_UARTEx_WakeupCallback can be implemented in the user file.
262
   */
265
   */
263
}
266
}
264
 
267
 
-
 
268
#endif /* USART_CR3_WUFIE */
265
#endif /* USART_CR1_UESM */
269
#endif /* USART_CR1_UESM */
266
 
270
 
267
/**
271
/**
268
  * @}
272
  * @}
269
  */
273
  */
Line 283... Line 287...
283
         trigger: address match, Start Bit detection or RXNE bit status.
287
         trigger: address match, Start Bit detection or RXNE bit status.
284
     (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
288
     (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
285
     (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
289
     (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
286
#endif
290
#endif
287
 
291
 
-
 
292
    [..] This subsection also provides a set of additional functions providing enhanced reception
-
 
293
    services to user. (For example, these functions allow application to handle use cases
-
 
294
    where number of data to be received is unknown).
-
 
295
 
-
 
296
    (#) Compared to standard reception services which only consider number of received
-
 
297
        data elements as reception completion criteria, these functions also consider additional events
-
 
298
        as triggers for updating reception status to caller :
-
 
299
       (+) Detection of inactivity period (RX line has not been active for a given period).
-
 
300
          (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
-
 
301
               for 1 frame time, after last received byte.
-
 
302
          (++) RX inactivity detected by RTO, i.e. line has been in idle state
-
 
303
               for a programmable time, after last received byte.
-
 
304
       (+) Detection that a specific character has been received.
-
 
305
 
-
 
306
    (#) There are two mode of transfer:
-
 
307
       (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
-
 
308
           or till IDLE event occurs. Reception is handled only during function execution.
-
 
309
           When function exits, no data reception could occur. HAL status and number of actually received data elements,
-
 
310
           are returned by function after finishing transfer.
-
 
311
       (+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
-
 
312
           These API's return the HAL status.
-
 
313
           The end of the data processing will be indicated through the
-
 
314
           dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
-
 
315
           The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
-
 
316
           The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
-
 
317
 
-
 
318
    (#) Blocking mode API:
-
 
319
        (+) HAL_UARTEx_ReceiveToIdle()
-
 
320
 
-
 
321
    (#) Non-Blocking mode API with Interrupt:
-
 
322
        (+) HAL_UARTEx_ReceiveToIdle_IT()
-
 
323
 
-
 
324
    (#) Non-Blocking mode API with DMA:
-
 
325
        (+) HAL_UARTEx_ReceiveToIdle_DMA()
-
 
326
 
288
@endverbatim
327
@endverbatim
289
  * @{
328
  * @{
290
  */
329
  */
291
 
330
 
292
/**
331
/**
Line 357... Line 396...
357
  huart->gState = HAL_UART_STATE_BUSY;
396
  huart->gState = HAL_UART_STATE_BUSY;
358
 
397
 
359
  /* Disable the Peripheral */
398
  /* Disable the Peripheral */
360
  __HAL_UART_DISABLE(huart);
399
  __HAL_UART_DISABLE(huart);
361
 
400
 
-
 
401
#if defined(USART_CR3_WUS)
362
  /* Set the wake-up selection scheme */
402
  /* Set the wake-up selection scheme */
363
  MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
403
  MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
-
 
404
#endif /* USART_CR3_WUS */
364
 
405
 
365
  if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
406
  if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
366
  {
407
  {
367
    UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
408
    UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
368
  }
409
  }
369
 
410
 
370
  /* Enable the Peripheral */
411
  /* Enable the Peripheral */
371
  __HAL_UART_ENABLE(huart);
412
  __HAL_UART_ENABLE(huart);
372
 
413
 
373
  /* Init tickstart for timeout managment*/
414
  /* Init tickstart for timeout management */
374
  tickstart = HAL_GetTick();
415
  tickstart = HAL_GetTick();
375
 
416
 
376
  /* Wait until REACK flag is set */
417
  /* Wait until REACK flag is set */
377
  if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
418
  if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
378
  {
419
  {
Line 400... Line 441...
400
{
441
{
401
  /* Process Locked */
442
  /* Process Locked */
402
  __HAL_LOCK(huart);
443
  __HAL_LOCK(huart);
403
 
444
 
404
  /* Set UESM bit */
445
  /* Set UESM bit */
405
  SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
446
  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
406
 
447
 
407
  /* Process Unlocked */
448
  /* Process Unlocked */
408
  __HAL_UNLOCK(huart);
449
  __HAL_UNLOCK(huart);
409
 
450
 
410
  return HAL_OK;
451
  return HAL_OK;
Line 419... Line 460...
419
{
460
{
420
  /* Process Locked */
461
  /* Process Locked */
421
  __HAL_LOCK(huart);
462
  __HAL_LOCK(huart);
422
 
463
 
423
  /* Clear UESM bit */
464
  /* Clear UESM bit */
424
  CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
465
  ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
425
 
466
 
426
  /* Process Unlocked */
467
  /* Process Unlocked */
427
  __HAL_UNLOCK(huart);
468
  __HAL_UNLOCK(huart);
428
 
469
 
429
  return HAL_OK;
470
  return HAL_OK;
430
}
471
}
431
 
472
 
432
#endif /* USART_CR1_UESM */
473
#endif /* USART_CR1_UESM */
433
/**
474
/**
-
 
475
  * @brief Receive an amount of data in blocking mode till either the expected number of data
-
 
476
  *        is received or an IDLE event occurs.
-
 
477
  * @note  HAL_OK is returned if reception is completed (expected number of data has been received)
-
 
478
  *        or if reception is stopped after IDLE event (less than the expected number of data has been received)
-
 
479
  *        In this case, RxLen output parameter indicates number of data available in reception buffer.
-
 
480
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
-
 
481
  *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
-
 
482
  *        of uint16_t available through pData.
-
 
483
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
-
 
484
  *         address of user data buffer for storing data to be received, should be aligned on a half word frontier
-
 
485
  *         (16 bits) (as received data will be handled using uint16_t pointer cast). Depending on compilation chain,
-
 
486
  *         use of specific alignment compilation directives or pragmas might be required to ensure proper
-
 
487
  *         alignment for pData.
-
 
488
  * @param huart   UART handle.
-
 
489
  * @param pData   Pointer to data buffer (uint8_t or uint16_t data elements).
-
 
490
  * @param Size    Amount of data elements (uint8_t or uint16_t) to be received.
-
 
491
  * @param RxLen   Number of data elements finally received
-
 
492
  *                (could be lower than Size, in case reception ends on IDLE event)
-
 
493
  * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
-
 
494
  * @retval HAL status
-
 
495
  */
-
 
496
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
-
 
497
                                           uint32_t Timeout)
-
 
498
{
-
 
499
  uint8_t  *pdata8bits;
-
 
500
  uint16_t *pdata16bits;
-
 
501
  uint16_t uhMask;
-
 
502
  uint32_t tickstart;
-
 
503
 
-
 
504
  /* Check that a Rx process is not already ongoing */
-
 
505
  if (huart->RxState == HAL_UART_STATE_READY)
-
 
506
  {
-
 
507
    if ((pData == NULL) || (Size == 0U))
-
 
508
    {
-
 
509
      return  HAL_ERROR;
-
 
510
    }
-
 
511
 
-
 
512
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
-
 
513
       should be aligned on a uint16_t frontier, as data to be received from RDR will be
-
 
514
       handled through a uint16_t cast. */
-
 
515
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
-
 
516
    {
-
 
517
      if ((((uint32_t)pData) & 1U) != 0U)
-
 
518
      {
-
 
519
        return  HAL_ERROR;
-
 
520
      }
-
 
521
    }
-
 
522
 
-
 
523
    __HAL_LOCK(huart);
-
 
524
 
-
 
525
    huart->ErrorCode = HAL_UART_ERROR_NONE;
-
 
526
    huart->RxState = HAL_UART_STATE_BUSY_RX;
-
 
527
    huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
-
 
528
 
-
 
529
    /* Init tickstart for timeout management */
-
 
530
    tickstart = HAL_GetTick();
-
 
531
 
-
 
532
    huart->RxXferSize  = Size;
-
 
533
    huart->RxXferCount = Size;
-
 
534
 
-
 
535
    /* Computation of UART mask to apply to RDR register */
-
 
536
    UART_MASK_COMPUTATION(huart);
-
 
537
    uhMask = huart->Mask;
-
 
538
 
-
 
539
    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
-
 
540
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
-
 
541
    {
-
 
542
      pdata8bits  = NULL;
-
 
543
      pdata16bits = (uint16_t *) pData;
-
 
544
    }
-
 
545
    else
-
 
546
    {
-
 
547
      pdata8bits  = pData;
-
 
548
      pdata16bits = NULL;
-
 
549
    }
-
 
550
 
-
 
551
    __HAL_UNLOCK(huart);
-
 
552
 
-
 
553
    /* Initialize output number of received elements */
-
 
554
    *RxLen = 0U;
-
 
555
 
-
 
556
    /* as long as data have to be received */
-
 
557
    while (huart->RxXferCount > 0U)
-
 
558
    {
-
 
559
      /* Check if IDLE flag is set */
-
 
560
      if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
-
 
561
      {
-
 
562
        /* Clear IDLE flag in ISR */
-
 
563
        __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
-
 
564
 
-
 
565
        /* If Set, but no data ever received, clear flag without exiting loop */
-
 
566
        /* If Set, and data has already been received, this means Idle Event is valid : End reception */
-
 
567
        if (*RxLen > 0U)
-
 
568
        {
-
 
569
          huart->RxState = HAL_UART_STATE_READY;
-
 
570
 
-
 
571
          return HAL_OK;
-
 
572
        }
-
 
573
      }
-
 
574
 
-
 
575
      /* Check if RXNE flag is set */
-
 
576
      if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
-
 
577
      {
-
 
578
        if (pdata8bits == NULL)
-
 
579
        {
-
 
580
          *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
-
 
581
          pdata16bits++;
-
 
582
        }
-
 
583
        else
-
 
584
        {
-
 
585
          *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
-
 
586
          pdata8bits++;
-
 
587
        }
-
 
588
        /* Increment number of received elements */
-
 
589
        *RxLen += 1U;
-
 
590
        huart->RxXferCount--;
-
 
591
      }
-
 
592
 
-
 
593
      /* Check for the Timeout */
-
 
594
      if (Timeout != HAL_MAX_DELAY)
-
 
595
      {
-
 
596
        if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
-
 
597
        {
-
 
598
          huart->RxState = HAL_UART_STATE_READY;
-
 
599
 
-
 
600
          return HAL_TIMEOUT;
-
 
601
        }
-
 
602
      }
-
 
603
    }
-
 
604
 
-
 
605
    /* Set number of received elements in output parameter : RxLen */
-
 
606
    *RxLen = huart->RxXferSize - huart->RxXferCount;
-
 
607
    /* At end of Rx process, restore huart->RxState to Ready */
-
 
608
    huart->RxState = HAL_UART_STATE_READY;
-
 
609
 
-
 
610
    return HAL_OK;
-
 
611
  }
-
 
612
  else
-
 
613
  {
-
 
614
    return HAL_BUSY;
-
 
615
  }
-
 
616
}
-
 
617
 
-
 
618
/**
-
 
619
  * @brief Receive an amount of data in interrupt mode till either the expected number of data
-
 
620
  *        is received or an IDLE event occurs.
-
 
621
  * @note  Reception is initiated by this function call. Further progress of reception is achieved thanks
-
 
622
  *        to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
-
 
623
  *        number of received data elements.
-
 
624
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
-
 
625
  *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
-
 
626
  *        of uint16_t available through pData.
-
 
627
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
-
 
628
  *        address of user data buffer for storing data to be received, should be aligned on a half word frontier
-
 
629
  *        (16 bits) (as received data will be handled using uint16_t pointer cast). Depending on compilation chain,
-
 
630
  *        use of specific alignment compilation directives or pragmas might be required
-
 
631
  *        to ensure proper alignment for pData.
-
 
632
  * @param huart UART handle.
-
 
633
  * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
-
 
634
  * @param Size  Amount of data elements (uint8_t or uint16_t) to be received.
-
 
635
  * @retval HAL status
-
 
636
  */
-
 
637
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
-
 
638
{
-
 
639
  HAL_StatusTypeDef status;
-
 
640
 
-
 
641
  /* Check that a Rx process is not already ongoing */
-
 
642
  if (huart->RxState == HAL_UART_STATE_READY)
-
 
643
  {
-
 
644
    if ((pData == NULL) || (Size == 0U))
-
 
645
    {
-
 
646
      return HAL_ERROR;
-
 
647
    }
-
 
648
 
-
 
649
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
-
 
650
       should be aligned on a uint16_t frontier, as data to be received from RDR will be
-
 
651
       handled through a uint16_t cast. */
-
 
652
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
-
 
653
    {
-
 
654
      if ((((uint32_t)pData) & 1U) != 0U)
-
 
655
      {
-
 
656
        return  HAL_ERROR;
-
 
657
      }
-
 
658
    }
-
 
659
 
-
 
660
    __HAL_LOCK(huart);
-
 
661
 
-
 
662
    /* Set Reception type to reception till IDLE Event*/
-
 
663
    huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
-
 
664
 
-
 
665
    status =  UART_Start_Receive_IT(huart, pData, Size);
-
 
666
 
-
 
667
    /* Check Rx process has been successfully started */
-
 
668
    if (status == HAL_OK)
-
 
669
    {
-
 
670
      if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
-
 
671
      {
-
 
672
        __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
-
 
673
        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
-
 
674
      }
-
 
675
      else
-
 
676
      {
-
 
677
        /* In case of errors already pending when reception is started,
-
 
678
           Interrupts may have already been raised and lead to reception abortion.
-
 
679
           (Overrun error for instance).
-
 
680
           In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
-
 
681
        status = HAL_ERROR;
-
 
682
      }
-
 
683
    }
-
 
684
 
-
 
685
    return status;
-
 
686
  }
-
 
687
  else
-
 
688
  {
-
 
689
    return HAL_BUSY;
-
 
690
  }
-
 
691
}
-
 
692
 
-
 
693
/**
-
 
694
  * @brief Receive an amount of data in DMA mode till either the expected number
-
 
695
  *        of data is received or an IDLE event occurs.
-
 
696
  * @note  Reception is initiated by this function call. Further progress of reception is achieved thanks
-
 
697
  *        to DMA services, transferring automatically received data elements in user reception buffer and
-
 
698
  *        calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
-
 
699
  *        reception phase as ended. In all cases, callback execution will indicate number of received data elements.
-
 
700
  * @note  When the UART parity is enabled (PCE = 1), the received data contain
-
 
701
  *        the parity bit (MSB position).
-
 
702
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
-
 
703
  *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
-
 
704
  *        of uint16_t available through pData.
-
 
705
  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
-
 
706
  *        address of user data buffer for storing data to be received, should be aligned on a half word frontier
-
 
707
  *        (16 bits) (as received data will be handled by DMA from halfword frontier). Depending on compilation chain,
-
 
708
  *        use of specific alignment compilation directives or pragmas might be required
-
 
709
  *        to ensure proper alignment for pData.
-
 
710
  * @param huart UART handle.
-
 
711
  * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
-
 
712
  * @param Size  Amount of data elements (uint8_t or uint16_t) to be received.
-
 
713
  * @retval HAL status
-
 
714
  */
-
 
715
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
-
 
716
{
-
 
717
  HAL_StatusTypeDef status;
-
 
718
 
-
 
719
  /* Check that a Rx process is not already ongoing */
-
 
720
  if (huart->RxState == HAL_UART_STATE_READY)
-
 
721
  {
-
 
722
    if ((pData == NULL) || (Size == 0U))
-
 
723
    {
-
 
724
      return HAL_ERROR;
-
 
725
    }
-
 
726
 
-
 
727
    /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
-
 
728
       should be aligned on a uint16_t frontier, as data copy from RDR will be
-
 
729
       handled by DMA from a uint16_t frontier. */
-
 
730
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
-
 
731
    {
-
 
732
      if ((((uint32_t)pData) & 1U) != 0U)
-
 
733
      {
-
 
734
        return  HAL_ERROR;
-
 
735
      }
-
 
736
    }
-
 
737
 
-
 
738
    __HAL_LOCK(huart);
-
 
739
 
-
 
740
    /* Set Reception type to reception till IDLE Event*/
-
 
741
    huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
-
 
742
 
-
 
743
    status =  UART_Start_Receive_DMA(huart, pData, Size);
-
 
744
 
-
 
745
    /* Check Rx process has been successfully started */
-
 
746
    if (status == HAL_OK)
-
 
747
    {
-
 
748
      if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
-
 
749
      {
-
 
750
        __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
-
 
751
        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
-
 
752
      }
-
 
753
      else
-
 
754
      {
-
 
755
        /* In case of errors already pending when reception is started,
-
 
756
           Interrupts may have already been raised and lead to reception abortion.
-
 
757
           (Overrun error for instance).
-
 
758
           In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
-
 
759
        status = HAL_ERROR;
-
 
760
      }
-
 
761
    }
-
 
762
 
-
 
763
    return status;
-
 
764
  }
-
 
765
  else
-
 
766
  {
-
 
767
    return HAL_BUSY;
-
 
768
  }
-
 
769
}
-
 
770
 
-
 
771
/**
434
  * @}
772
  * @}
435
  */
773
  */
436
 
774
 
437
/**
775
/**
438
  * @}
776
  * @}