| /** |
| ****************************************************************************** |
| * @file stm32h7xx_hal_jpeg.c |
| * @author MCD Application Team |
| * @brief JPEG HAL module driver. |
| * This file provides firmware functions to manage the following |
| * functionalities of the JPEG encoder/decoder peripheral: |
| * + Initialization and de-initialization functions |
| * + JPEG processing functions encoding and decoding |
| * + JPEG decoding Getting Info and encoding configuration setting |
| * + JPEG enable/disable header parsing functions (for decoding) |
| * + JPEG Input/Output Buffer configuration. |
| * + JPEG callback functions |
| * + JPEG Abort/Pause/Resume functions |
| * + JPEG custom quantization tables setting functions |
| * + IRQ handler management |
| * + Peripheral State and Error functions |
| * |
| ****************************************************************************** |
| * @attention |
| * |
| * Copyright (c) 2017 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. |
| * |
| ****************************************************************************** |
| @verbatim |
| ============================================================================== |
| ##### How to use this driver ##### |
| ============================================================================== |
| [..] |
| (#) Initialize the JPEG peripheral using HAL_JPEG_Init : No initialization parameters are required. |
| Only the call to HAL_JPEG_Init is necessary to initialize the JPEG peripheral. |
| |
| (#) If operation is JPEG encoding use function HAL_JPEG_ConfigEncoding to set |
| the encoding parameters (mandatory before calling the encoding function). |
| the application can change the encoding parameter ImageQuality from |
| 1 to 100 to obtain a more or less quality (visual quality vs the original row image), |
| and inversely more or less jpg file size. |
| |
| (#) Note that for decoding operation the JPEG peripheral output data are organized in |
| YCbCr blocks called MCU (Minimum Coded Unit) as defioned in the JPEG specification |
| ISO/IEC 10918-1 standard. |
| It is up to the application to transform these YCbCr blocks to RGB data that can be display. |
| |
| Respectively, for Encoding operation the JPEG peripheral input should be organized |
| in YCbCr MCU blocks. It is up to the application to perform the necessary RGB to YCbCr |
| MCU blocks transformation before feeding the JPEG peripheral with data. |
| |
| (#) Use functions HAL_JPEG_Encode and HAL_JPEG_Decode to start respectively |
| a JPEG encoding/decoding operation in polling method (blocking). |
| |
| (#) Use functions HAL_JPEG_Encode_IT and HAL_JPEG_Decode_IT to start respectively |
| a JPEG encoding/decoding operation with Interrupt method (not blocking). |
| |
| (#) Use functions HAL_JPEG_Encode_DMA and HAL_JPEG_Decode_DMA to start respectively |
| a JPEG encoding/decoding operation with DMA method (not blocking). |
| |
| (#) Callback HAL_JPEG_InfoReadyCallback is asserted if the current operation |
| is a JPEG decoding to provide the application with JPEG image parameters. |
| This callback is asserted when the JPEG peripheral successfully parse the |
| JPEG header. |
| |
| (#) Callback HAL_JPEG_GetDataCallback is asserted for both encoding and decoding |
| operations to inform the application that the input buffer has been |
| consumed by the peripheral and to ask for a new data chunk if the operation |
| (encoding/decoding) has not been complete yet. |
| |
| (++) This CallBack should be implemented in the application side. It should |
| call the function HAL_JPEG_ConfigInputBuffer if new input data are available, |
| or call HAL_JPEG_Pause with parameter XferSelection set to JPEG_PAUSE_RESUME_INPUT |
| to inform the JPEG HAL driver that the ongoing operation shall pause waiting for the |
| application to provide a new input data chunk. |
| Once the application succeed getting new data and if the input has been paused, |
| the application can call the function HAL_JPEG_ConfigInputBuffer to set the new |
| input buffer and size, then resume the JPEG HAL input by calling new function HAL_JPEG_Resume. |
| If the application has ended feeding the HAL JPEG with input data (no more input data), the application |
| Should call the function HAL_JPEG_ConfigInputBuffer (within the callback HAL_JPEG_GetDataCallback) |
| with the parameter InDataLength set to zero. |
| |
| (++) The mechanism of HAL_JPEG_ConfigInputBuffer/HAL_JPEG_Pause/HAL_JPEG_Resume allows |
| to the application to provide the input data (for encoding or decoding) by chunks. |
| If the new input data chunk is not available (because data should be read from an input file |
| for example) the application can pause the JPEG input (using function HAL_JPEG_Pause) |
| Once the new input data chunk is available ( read from a file for example), the application |
| can call the function HAL_JPEG_ConfigInputBuffer to provide the HAL with the new chunk |
| then resume the JPEG HAL input by calling function HAL_JPEG_Resume. |
| |
| (++) The application can call functions HAL_JPEG_ConfigInputBuffer then HAL_JPEG_Resume. |
| any time (outside the HAL_JPEG_GetDataCallback) Once the new input chunk data available. |
| However, to keep data coherency, the function HAL_JPEG_Pause must be imperatively called |
| (if necessary) within the callback HAL_JPEG_GetDataCallback, i.e when the HAL JPEG has ended |
| Transferring the previous chunk buffer to the JPEG peripheral. |
| |
| (#) Callback HAL_JPEG_DataReadyCallback is asserted when the HAL JPEG driver |
| has filled the given output buffer with the given size. |
| |
| (++) This CallBack should be implemented in the application side. It should |
| call the function HAL_JPEG_ConfigOutputBuffer to provide the HAL JPEG driver |
| with the new output buffer location and size to be used to store next data chunk. |
| if the application is not ready to provide the output chunk location then it can |
| call the function HAL_JPEG_Pause with parameter XferSelection set to JPEG_PAUSE_RESUME_OUTPUT |
| to inform the JPEG HAL driver that it shall pause output data. Once the application |
| is ready to receive the new data chunk (output buffer location free or available) it should call |
| the function HAL_JPEG_ConfigOutputBuffer to provide the HAL JPEG driver |
| with the new output chunk buffer location and size, then call HAL_JPEG_Resume |
| to inform the HAL that it shall resume outputting data in the given output buffer. |
| |
| (++) The mechanism of HAL_JPEG_ConfigOutputBuffer/HAL_JPEG_Pause/HAL_JPEG_Resume allows |
| the application to receive data from the JPEG peripheral by chunks. when a chunk |
| is received, the application can pause the HAL JPEG output data to be able to process |
| these received data (YCbCr to RGB conversion in case of decoding or data storage in case |
| of encoding). |
| |
| (++) The application can call functions HAL_JPEG_ ConfigOutputBuffer then HAL_JPEG_Resume. |
| any time (outside the HAL_JPEG_DataReadyCallback) Once the output data buffer is free to use. |
| However, to keep data coherency, the function HAL_JPEG_Pause must be imperatively called |
| (if necessary) within the callback HAL_JPEG_ DataReadyCallback, i.e when the HAL JPEG has ended |
| Transferring the previous chunk buffer from the JPEG peripheral to the application. |
| |
| (#) Callback HAL_JPEG_EncodeCpltCallback is asserted when the HAL JPEG driver has |
| ended the current JPEG encoding operation, and all output data has been transmitted |
| to the application. |
| |
| (#) Callback HAL_JPEG_DecodeCpltCallback is asserted when the HAL JPEG driver has |
| ended the current JPEG decoding operation. and all output data has been transmitted |
| to the application. |
| |
| (#) Callback HAL_JPEG_ErrorCallback is asserted when an error occurred during |
| the current operation. the application can call the function HAL_JPEG_GetError() |
| to retrieve the error codes. |
| |
| (#) By default the HAL JPEG driver uses the default quantization tables |
| as provide in the JPEG specification (ISO/IEC 10918-1 standard) for encoding. |
| User can change these default tables if necessary using the function HAL_JPEG_SetUserQuantTables |
| Note that for decoding the quantization tables are automatically extracted from |
| the JPEG header. |
| |
| (#) To control JPEG state you can use the following function: HAL_JPEG_GetState() |
| |
| *** JPEG HAL driver macros list *** |
| ============================================= |
| [..] |
| Below the list of most used macros in JPEG HAL driver. |
| |
| (+) __HAL_JPEG_RESET_HANDLE_STATE : Reset JPEG handle state. |
| (+) __HAL_JPEG_ENABLE : Enable the JPEG peripheral. |
| (+) __HAL_JPEG_DISABLE : Disable the JPEG peripheral. |
| (+) __HAL_JPEG_GET_FLAG : Check the specified JPEG status flag. |
| (+) __HAL_JPEG_CLEAR_FLAG : Clear the specified JPEG status flag. |
| (+) __HAL_JPEG_ENABLE_IT : Enable the specified JPEG Interrupt. |
| (+) __HAL_JPEG_DISABLE_IT : Disable the specified JPEG Interrupt. |
| (+) __HAL_JPEG_GET_IT_SOURCE : returns the state of the specified JPEG Interrupt (Enabled or disabled). |
| |
| *** Callback registration *** |
| ============================================= |
| |
| The compilation define USE_HAL_JPEG_REGISTER_CALLBACKS when set to 1 |
| allows the user to configure dynamically the driver callbacks. |
| Use Functions HAL_JPEG_RegisterCallback() or HAL_JPEG_RegisterXXXCallback() |
| to register an interrupt callback. |
| |
| Function HAL_JPEG_RegisterCallback() allows to register following callbacks: |
| (+) EncodeCpltCallback : callback for end of encoding operation. |
| (+) DecodeCpltCallback : callback for end of decoding operation. |
| (+) ErrorCallback : callback for error detection. |
| (+) MspInitCallback : JPEG MspInit. |
| (+) MspDeInitCallback : JPEG MspDeInit. |
| This function takes as parameters the HAL peripheral handle, the Callback ID |
| and a pointer to the user callback function. |
| |
| For specific callbacks InfoReadyCallback, GetDataCallback and DataReadyCallback use dedicated |
| register callbacks : respectively HAL_JPEG_RegisterInfoReadyCallback(), |
| HAL_JPEG_RegisterGetDataCallback() and HAL_JPEG_RegisterDataReadyCallback(). |
| |
| Use function HAL_JPEG_UnRegisterCallback() to reset a callback to the default |
| weak function. |
| HAL_JPEG_UnRegisterCallback() takes as parameters the HAL peripheral handle, |
| and the Callback ID. |
| This function allows to reset following callbacks: |
| (+) EncodeCpltCallback : callback for end of encoding operation. |
| (+) DecodeCpltCallback : callback for end of decoding operation. |
| (+) ErrorCallback : callback for error detection. |
| (+) MspInitCallback : JPEG MspInit. |
| (+) MspDeInitCallback : JPEG MspDeInit. |
| |
| For callbacks InfoReadyCallback, GetDataCallback and DataReadyCallback use dedicated |
| unregister callbacks : respectively HAL_JPEG_UnRegisterInfoReadyCallback(), |
| HAL_JPEG_UnRegisterGetDataCallback() and HAL_JPEG_UnRegisterDataReadyCallback(). |
| |
| By default, after the HAL_JPEG_Init() and when the state is HAL_JPEG_STATE_RESET |
| all callbacks are set to the corresponding weak functions : |
| examples HAL_JPEG_DecodeCpltCallback() , HAL_JPEG_GetDataCallback(). |
| Exception done for MspInit and MspDeInit functions that are |
| reset to the legacy weak function in the HAL_JPEG_Init()/ HAL_JPEG_DeInit() only when |
| these callbacks are null (not registered beforehand). |
| if not, MspInit or MspDeInit are not null, the HAL_JPEG_Init() / HAL_JPEG_DeInit() |
| keep and use the user MspInit/MspDeInit functions (registered beforehand) |
| |
| Callbacks can be registered/unregistered in HAL_JPEG_STATE_READY state only. |
| Exception done MspInit/MspDeInit callbacks that can be registered/unregistered |
| in HAL_JPEG_STATE_READY or HAL_JPEG_STATE_RESET state, |
| thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. |
| In that case first register the MspInit/MspDeInit user callbacks |
| using HAL_JPEG_RegisterCallback() before calling HAL_JPEG_DeInit() |
| or HAL_JPEG_Init() function. |
| |
| When The compilation define USE_HAL_JPEG_REGISTER_CALLBACKS is set to 0 or |
| not defined, the callback registration feature is not available and all callbacks |
| are set to the corresponding weak functions. |
| |
| @endverbatim |
| ****************************************************************************** |
| */ |
| |
| /* Includes ------------------------------------------------------------------*/ |
| #include "stm32h7xx_hal.h" |
| |
| /** @addtogroup STM32H7xx_HAL_Driver |
| * @{ |
| */ |
| |
| #ifdef HAL_JPEG_MODULE_ENABLED |
| |
| #if defined (JPEG) |
| |
| /** @defgroup JPEG JPEG |
| * @brief JPEG HAL module driver. |
| * @{ |
| */ |
| |
| /* Private define ------------------------------------------------------------*/ |
| /** @addtogroup JPEG_Private_Constants |
| * @{ |
| */ |
| #define JPEG_TIMEOUT_VALUE ((uint32_t)1000) /* 1s */ |
| #define JPEG_AC_HUFF_TABLE_SIZE ((uint32_t)162) /* Huffman AC table size : 162 codes*/ |
| #define JPEG_DC_HUFF_TABLE_SIZE ((uint32_t)12) /* Huffman AC table size : 12 codes*/ |
| |
| #define JPEG_FIFO_SIZE ((uint32_t)16U) /* JPEG Input/Output HW FIFO size in words*/ |
| |
| #define JPEG_FIFO_TH_SIZE ((uint32_t)8U) /* JPEG Input/Output HW FIFO Threshold in words*/ |
| |
| #define JPEG_INTERRUPT_MASK ((uint32_t)0x0000007EU) /* JPEG Interrupt Mask*/ |
| |
| #define JPEG_CONTEXT_ENCODE ((uint32_t)0x00000001) /* JPEG context : operation is encoding*/ |
| #define JPEG_CONTEXT_DECODE ((uint32_t)0x00000002) /* JPEG context : operation is decoding*/ |
| #define JPEG_CONTEXT_OPERATION_MASK ((uint32_t)0x00000003) /* JPEG context : operation Mask */ |
| |
| #define JPEG_CONTEXT_POLLING ((uint32_t)0x00000004) /* JPEG context : Transfer use Polling */ |
| #define JPEG_CONTEXT_IT ((uint32_t)0x00000008) /* JPEG context : Transfer use Interrupt */ |
| #define JPEG_CONTEXT_DMA ((uint32_t)0x0000000C) /* JPEG context : Transfer use DMA */ |
| #define JPEG_CONTEXT_METHOD_MASK ((uint32_t)0x0000000C) /* JPEG context : Transfer Mask */ |
| |
| |
| #define JPEG_CONTEXT_CONF_ENCODING ((uint32_t)0x00000100) /* JPEG context : encoding config done */ |
| |
| #define JPEG_CONTEXT_PAUSE_INPUT ((uint32_t)0x00001000) /* JPEG context : Pause Input */ |
| #define JPEG_CONTEXT_PAUSE_OUTPUT ((uint32_t)0x00002000) /* JPEG context : Pause Output */ |
| |
| #define JPEG_CONTEXT_CUSTOM_TABLES ((uint32_t)0x00004000) /* JPEG context : Use custom quantization tables */ |
| |
| #define JPEG_CONTEXT_ENDING_DMA ((uint32_t)0x00008000) /* JPEG context : ending with DMA in progress */ |
| |
| #define JPEG_PROCESS_ONGOING ((uint32_t)0x00000000) /* Process is on going */ |
| #define JPEG_PROCESS_DONE ((uint32_t)0x00000001) /* Process is done (ends) */ |
| /** |
| * @} |
| */ |
| |
| /* Private typedef -----------------------------------------------------------*/ |
| /** @addtogroup JPEG_Private_Types |
| * @{ |
| */ |
| |
| /* |
| JPEG Huffman Table Structure definition : |
| This implementation of Huffman table structure is compliant with ISO/IEC 10918-1 standard , Annex C Huffman Table specification |
| */ |
| typedef struct |
| { |
| /* These two fields directly represent the contents of a JPEG DHT marker */ |
| uint8_t Bits[16]; /*!< bits[k] = # of symbols with codes of length k bits, this parameter corresponds to BITS list in the Annex C */ |
| |
| uint8_t HuffVal[162]; /*!< The symbols, in order of incremented code length, this parameter corresponds to HUFFVAL list in the Annex C */ |
| |
| |
| } JPEG_ACHuffTableTypeDef; |
| |
| typedef struct |
| { |
| /* These two fields directly represent the contents of a JPEG DHT marker */ |
| uint8_t Bits[16]; /*!< bits[k] = # of symbols with codes of length k bits, this parameter corresponds to BITS list in the Annex C */ |
| |
| uint8_t HuffVal[12]; /*!< The symbols, in order of incremented code length, this parameter corresponds to HUFFVAL list in the Annex C */ |
| |
| |
| } JPEG_DCHuffTableTypeDef; |
| |
| typedef struct |
| { |
| uint8_t CodeLength[JPEG_AC_HUFF_TABLE_SIZE]; /*!< Code length */ |
| |
| uint32_t HuffmanCode[JPEG_AC_HUFF_TABLE_SIZE]; /*!< HuffmanCode */ |
| |
| } JPEG_AC_HuffCodeTableTypeDef; |
| |
| typedef struct |
| { |
| uint8_t CodeLength[JPEG_DC_HUFF_TABLE_SIZE]; /*!< Code length */ |
| |
| uint32_t HuffmanCode[JPEG_DC_HUFF_TABLE_SIZE]; /*!< HuffmanCode */ |
| |
| } JPEG_DC_HuffCodeTableTypeDef; |
| /** |
| * @} |
| */ |
| |
| /* Private macro -------------------------------------------------------------*/ |
| |
| /* Private variables ---------------------------------------------------------*/ |
| /** @addtogroup JPEG_Private_Variables |
| * @{ |
| */ |
| |
| static const JPEG_DCHuffTableTypeDef JPEG_DCLUM_HuffTable = |
| { |
| { 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, /*Bits*/ |
| |
| { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb } /*HUFFVAL */ |
| |
| }; |
| |
| static const JPEG_DCHuffTableTypeDef JPEG_DCCHROM_HuffTable = |
| { |
| { 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }, /*Bits*/ |
| |
| { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb } /*HUFFVAL */ |
| }; |
| |
| static const JPEG_ACHuffTableTypeDef JPEG_ACLUM_HuffTable = |
| { |
| { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }, /*Bits*/ |
| |
| { |
| 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, /*HUFFVAL */ |
| 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, |
| 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, |
| 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, |
| 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, |
| 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, |
| 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, |
| 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, |
| 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, |
| 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, |
| 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, |
| 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, |
| 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, |
| 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, |
| 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, |
| 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, |
| 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, |
| 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, |
| 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, |
| 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, |
| 0xf9, 0xfa |
| } |
| }; |
| |
| static const JPEG_ACHuffTableTypeDef JPEG_ACCHROM_HuffTable = |
| { |
| { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }, /*Bits*/ |
| |
| { |
| 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, /*HUFFVAL */ |
| 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, |
| 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, |
| 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, |
| 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, |
| 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, |
| 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, |
| 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, |
| 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, |
| 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, |
| 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, |
| 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, |
| 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, |
| 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, |
| 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, |
| 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, |
| 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, |
| 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, |
| 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, |
| 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, |
| 0xf9, 0xfa |
| } |
| }; |
| |
| static const uint8_t JPEG_ZIGZAG_ORDER[JPEG_QUANT_TABLE_SIZE] = |
| { |
| 0, 1, 8, 16, 9, 2, 3, 10, |
| 17, 24, 32, 25, 18, 11, 4, 5, |
| 12, 19, 26, 33, 40, 48, 41, 34, |
| 27, 20, 13, 6, 7, 14, 21, 28, |
| 35, 42, 49, 56, 57, 50, 43, 36, |
| 29, 22, 15, 23, 30, 37, 44, 51, |
| 58, 59, 52, 45, 38, 31, 39, 46, |
| 53, 60, 61, 54, 47, 55, 62, 63 |
| }; |
| /** |
| * @} |
| */ |
| |
| /* Private function prototypes -----------------------------------------------*/ |
| /** @addtogroup JPEG_Private_Functions_Prototypes |
| * @{ |
| */ |
| |
| static HAL_StatusTypeDef JPEG_Bits_To_SizeCodes(uint8_t *Bits, uint8_t *Huffsize, uint32_t *Huffcode, uint32_t *LastK); |
| static HAL_StatusTypeDef JPEG_DCHuff_BitsVals_To_SizeCodes(JPEG_DCHuffTableTypeDef *DC_BitsValsTable, |
| JPEG_DC_HuffCodeTableTypeDef *DC_SizeCodesTable); |
| static HAL_StatusTypeDef JPEG_ACHuff_BitsVals_To_SizeCodes(JPEG_ACHuffTableTypeDef *AC_BitsValsTable, |
| JPEG_AC_HuffCodeTableTypeDef *AC_SizeCodesTable); |
| static HAL_StatusTypeDef JPEG_Set_HuffDC_Mem(JPEG_HandleTypeDef *hjpeg, JPEG_DCHuffTableTypeDef *HuffTableDC, |
| const __IO uint32_t *DCTableAddress); |
| static HAL_StatusTypeDef JPEG_Set_HuffAC_Mem(JPEG_HandleTypeDef *hjpeg, JPEG_ACHuffTableTypeDef *HuffTableAC, |
| const __IO uint32_t *ACTableAddress); |
| static HAL_StatusTypeDef JPEG_Set_HuffEnc_Mem(JPEG_HandleTypeDef *hjpeg); |
| static void JPEG_Set_Huff_DHTMem(JPEG_HandleTypeDef *hjpeg); |
| static uint32_t JPEG_Set_Quantization_Mem(JPEG_HandleTypeDef *hjpeg, uint8_t *QTable, |
| __IO uint32_t *QTableAddress); |
| static void JPEG_SetColorYCBCR(JPEG_HandleTypeDef *hjpeg); |
| static void JPEG_SetColorGrayScale(JPEG_HandleTypeDef *hjpeg); |
| static void JPEG_SetColorCMYK(JPEG_HandleTypeDef *hjpeg); |
| |
| static void JPEG_Init_Process(JPEG_HandleTypeDef *hjpeg); |
| static uint32_t JPEG_Process(JPEG_HandleTypeDef *hjpeg); |
| static void JPEG_ReadInputData(JPEG_HandleTypeDef *hjpeg, uint32_t nbRequestWords); |
| static void JPEG_StoreOutputData(JPEG_HandleTypeDef *hjpeg, uint32_t nbOutputWords); |
| static uint32_t JPEG_GetQuality(JPEG_HandleTypeDef *hjpeg); |
| |
| static HAL_StatusTypeDef JPEG_DMA_StartProcess(JPEG_HandleTypeDef *hjpeg); |
| static void JPEG_DMA_ContinueProcess(JPEG_HandleTypeDef *hjpeg); |
| static void JPEG_DMA_EndProcess(JPEG_HandleTypeDef *hjpeg); |
| static void JPEG_DMA_PollResidualData(JPEG_HandleTypeDef *hjpeg); |
| static void JPEG_MDMAOutCpltCallback(MDMA_HandleTypeDef *hmdma); |
| static void JPEG_MDMAInCpltCallback(MDMA_HandleTypeDef *hmdma); |
| static void JPEG_MDMAErrorCallback(MDMA_HandleTypeDef *hmdma); |
| static void JPEG_MDMAOutAbortCallback(MDMA_HandleTypeDef *hmdma); |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup JPEG_Exported_Functions JPEG Exported Functions |
| * @{ |
| */ |
| |
| /** @defgroup JPEG_Exported_Functions_Group1 Initialization and de-initialization functions |
| * @brief Initialization and de-initialization functions. |
| * |
| @verbatim |
| ============================================================================== |
| ##### Initialization and de-initialization functions ##### |
| ============================================================================== |
| [..] This section provides functions allowing to: |
| (+) Initialize the JPEG peripheral and creates the associated handle |
| (+) DeInitialize the JPEG peripheral |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Initializes the JPEG according to the specified |
| * parameters in the JPEG_InitTypeDef and creates the associated handle. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Init(JPEG_HandleTypeDef *hjpeg) |
| { |
| /* These are the sample quantization tables given in JPEG spec ISO/IEC 10918-1 standard , section K.1. */ |
| static const uint8_t JPEG_LUM_QuantTable[JPEG_QUANT_TABLE_SIZE] = |
| { |
| 16, 11, 10, 16, 24, 40, 51, 61, |
| 12, 12, 14, 19, 26, 58, 60, 55, |
| 14, 13, 16, 24, 40, 57, 69, 56, |
| 14, 17, 22, 29, 51, 87, 80, 62, |
| 18, 22, 37, 56, 68, 109, 103, 77, |
| 24, 35, 55, 64, 81, 104, 113, 92, |
| 49, 64, 78, 87, 103, 121, 120, 101, |
| 72, 92, 95, 98, 112, 100, 103, 99 |
| }; |
| static const uint8_t JPEG_CHROM_QuantTable[JPEG_QUANT_TABLE_SIZE] = |
| { |
| 17, 18, 24, 47, 99, 99, 99, 99, |
| 18, 21, 26, 66, 99, 99, 99, 99, |
| 24, 26, 56, 99, 99, 99, 99, 99, |
| 47, 66, 99, 99, 99, 99, 99, 99, |
| 99, 99, 99, 99, 99, 99, 99, 99, |
| 99, 99, 99, 99, 99, 99, 99, 99, |
| 99, 99, 99, 99, 99, 99, 99, 99, |
| 99, 99, 99, 99, 99, 99, 99, 99 |
| }; |
| |
| /* Check the JPEG handle allocation */ |
| if (hjpeg == NULL) |
| { |
| return HAL_ERROR; |
| } |
| |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| if (hjpeg->State == HAL_JPEG_STATE_RESET) |
| { |
| /* Allocate lock resource and initialize it */ |
| hjpeg->Lock = HAL_UNLOCKED; |
| |
| hjpeg->InfoReadyCallback = HAL_JPEG_InfoReadyCallback; /* Legacy weak InfoReadyCallback */ |
| hjpeg->EncodeCpltCallback = HAL_JPEG_EncodeCpltCallback; /* Legacy weak EncodeCpltCallback */ |
| hjpeg->DecodeCpltCallback = HAL_JPEG_DecodeCpltCallback; /* Legacy weak DecodeCpltCallback */ |
| hjpeg->ErrorCallback = HAL_JPEG_ErrorCallback; /* Legacy weak ErrorCallback */ |
| hjpeg->GetDataCallback = HAL_JPEG_GetDataCallback; /* Legacy weak GetDataCallback */ |
| hjpeg->DataReadyCallback = HAL_JPEG_DataReadyCallback; /* Legacy weak DataReadyCallback */ |
| |
| if (hjpeg->MspInitCallback == NULL) |
| { |
| hjpeg->MspInitCallback = HAL_JPEG_MspInit; /* Legacy weak MspInit */ |
| } |
| |
| /* Init the low level hardware */ |
| hjpeg->MspInitCallback(hjpeg); |
| } |
| #else |
| if (hjpeg->State == HAL_JPEG_STATE_RESET) |
| { |
| /* Allocate lock resource and initialize it */ |
| hjpeg->Lock = HAL_UNLOCKED; |
| |
| /* Init the low level hardware : GPIO, CLOCK */ |
| HAL_JPEG_MspInit(hjpeg); |
| } |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_BUSY; |
| |
| /* Start the JPEG Core*/ |
| __HAL_JPEG_ENABLE(hjpeg); |
| |
| /* Stop the JPEG encoding/decoding process*/ |
| hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; |
| |
| /* Disable All Interrupts */ |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); |
| |
| |
| /* Flush input and output FIFOs*/ |
| hjpeg->Instance->CR |= JPEG_CR_IFF; |
| hjpeg->Instance->CR |= JPEG_CR_OFF; |
| |
| /* Clear all flags */ |
| __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); |
| |
| /* init default quantization tables*/ |
| hjpeg->QuantTable0 = (uint8_t *)((uint32_t)JPEG_LUM_QuantTable); |
| hjpeg->QuantTable1 = (uint8_t *)((uint32_t)JPEG_CHROM_QuantTable); |
| hjpeg->QuantTable2 = NULL; |
| hjpeg->QuantTable3 = NULL; |
| |
| /* init the default Huffman tables*/ |
| if (JPEG_Set_HuffEnc_Mem(hjpeg) != HAL_OK) |
| { |
| hjpeg->ErrorCode = HAL_JPEG_ERROR_HUFF_TABLE; |
| |
| return HAL_ERROR; |
| } |
| |
| /* Enable header processing*/ |
| hjpeg->Instance->CONFR1 |= JPEG_CONFR1_HDR; |
| |
| /* Reset JpegInCount and JpegOutCount */ |
| hjpeg->JpegInCount = 0; |
| hjpeg->JpegOutCount = 0; |
| |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| /* Reset the JPEG ErrorCode */ |
| hjpeg->ErrorCode = HAL_JPEG_ERROR_NONE; |
| |
| /*Clear the context filelds*/ |
| hjpeg->Context = 0; |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief DeInitializes the JPEG peripheral. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_DeInit(JPEG_HandleTypeDef *hjpeg) |
| { |
| /* Check the JPEG handle allocation */ |
| if (hjpeg == NULL) |
| { |
| return HAL_ERROR; |
| } |
| |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| if (hjpeg->MspDeInitCallback == NULL) |
| { |
| hjpeg->MspDeInitCallback = HAL_JPEG_MspDeInit; /* Legacy weak MspDeInit */ |
| } |
| |
| /* DeInit the low level hardware */ |
| hjpeg->MspDeInitCallback(hjpeg); |
| |
| #else |
| /* DeInit the low level hardware: CLOCK, NVIC.*/ |
| HAL_JPEG_MspDeInit(hjpeg); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_BUSY; |
| |
| /* Reset the JPEG ErrorCode */ |
| hjpeg->ErrorCode = HAL_JPEG_ERROR_NONE; |
| |
| /* Reset JpegInCount and JpegOutCount */ |
| hjpeg->JpegInCount = 0; |
| hjpeg->JpegOutCount = 0; |
| |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_RESET; |
| |
| /*Clear the context fields*/ |
| hjpeg->Context = 0; |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Initializes the JPEG MSP. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| __weak void HAL_JPEG_MspInit(JPEG_HandleTypeDef *hjpeg) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hjpeg); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_JPEG_MspInit could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief DeInitializes JPEG MSP. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| __weak void HAL_JPEG_MspDeInit(JPEG_HandleTypeDef *hjpeg) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hjpeg); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_JPEG_MspDeInit could be implemented in the user file |
| */ |
| } |
| |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| /** |
| * @brief Register a User JPEG Callback |
| * To be used instead of the weak predefined callback |
| * @param hjpeg JPEG handle |
| * @param CallbackID ID of the callback to be registered |
| * This parameter can be one of the following values: |
| * @arg @ref HAL_JPEG_ENCODE_CPLT_CB_ID Encode Complete callback ID |
| * @arg @ref HAL_JPEG_DECODE_CPLT_CB_ID Decode Complete callback ID |
| * @arg @ref HAL_JPEG_ERROR_CB_ID Error callback ID |
| * @arg @ref HAL_JPEG_MSPINIT_CB_ID MspInit callback ID |
| * @arg @ref HAL_JPEG_MSPDEINIT_CB_ID MspDeInit callback ID |
| * @param pCallback pointer to the Callback function |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_RegisterCallback(JPEG_HandleTypeDef *hjpeg, HAL_JPEG_CallbackIDTypeDef CallbackID, |
| pJPEG_CallbackTypeDef pCallback) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if (pCallback == NULL) |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| return HAL_ERROR; |
| } |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (HAL_JPEG_STATE_READY == hjpeg->State) |
| { |
| switch (CallbackID) |
| { |
| case HAL_JPEG_ENCODE_CPLT_CB_ID : |
| hjpeg->EncodeCpltCallback = pCallback; |
| break; |
| |
| case HAL_JPEG_DECODE_CPLT_CB_ID : |
| hjpeg->DecodeCpltCallback = pCallback; |
| break; |
| |
| case HAL_JPEG_ERROR_CB_ID : |
| hjpeg->ErrorCallback = pCallback; |
| break; |
| |
| case HAL_JPEG_MSPINIT_CB_ID : |
| hjpeg->MspInitCallback = pCallback; |
| break; |
| |
| case HAL_JPEG_MSPDEINIT_CB_ID : |
| hjpeg->MspDeInitCallback = pCallback; |
| break; |
| |
| default : |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else if (HAL_JPEG_STATE_RESET == hjpeg->State) |
| { |
| switch (CallbackID) |
| { |
| case HAL_JPEG_MSPINIT_CB_ID : |
| hjpeg->MspInitCallback = pCallback; |
| break; |
| |
| case HAL_JPEG_MSPDEINIT_CB_ID : |
| hjpeg->MspDeInitCallback = pCallback; |
| break; |
| |
| default : |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hjpeg); |
| return status; |
| } |
| |
| /** |
| * @brief Unregister a JPEG Callback |
| * JPEG callabck is redirected to the weak predefined callback |
| * @param hjpeg JPEG handle |
| * @param CallbackID ID of the callback to be unregistered |
| * This parameter can be one of the following values: |
| * This parameter can be one of the following values: |
| * @arg @ref HAL_JPEG_ENCODE_CPLT_CB_ID Encode Complete callback ID |
| * @arg @ref HAL_JPEG_DECODE_CPLT_CB_ID Decode Complete callback ID |
| * @arg @ref HAL_JPEG_ERROR_CB_ID Error callback ID |
| * @arg @ref HAL_JPEG_MSPINIT_CB_ID MspInit callback ID |
| * @arg @ref HAL_JPEG_MSPDEINIT_CB_ID MspDeInit callback ID |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_UnRegisterCallback(JPEG_HandleTypeDef *hjpeg, HAL_JPEG_CallbackIDTypeDef CallbackID) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (HAL_JPEG_STATE_READY == hjpeg->State) |
| { |
| switch (CallbackID) |
| { |
| case HAL_JPEG_ENCODE_CPLT_CB_ID : |
| hjpeg->EncodeCpltCallback = HAL_JPEG_EncodeCpltCallback; /* Legacy weak EncodeCpltCallback */ |
| break; |
| |
| case HAL_JPEG_DECODE_CPLT_CB_ID : |
| hjpeg->DecodeCpltCallback = HAL_JPEG_DecodeCpltCallback; /* Legacy weak DecodeCpltCallback */ |
| break; |
| |
| case HAL_JPEG_ERROR_CB_ID : |
| hjpeg->ErrorCallback = HAL_JPEG_ErrorCallback; /* Legacy weak ErrorCallback */ |
| break; |
| |
| case HAL_JPEG_MSPINIT_CB_ID : |
| hjpeg->MspInitCallback = HAL_JPEG_MspInit; /* Legacy weak MspInit */ |
| break; |
| |
| case HAL_JPEG_MSPDEINIT_CB_ID : |
| hjpeg->MspDeInitCallback = HAL_JPEG_MspDeInit; /* Legacy weak MspDeInit */ |
| break; |
| |
| default : |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else if (HAL_JPEG_STATE_RESET == hjpeg->State) |
| { |
| switch (CallbackID) |
| { |
| case HAL_JPEG_MSPINIT_CB_ID : |
| hjpeg->MspInitCallback = HAL_JPEG_MspInit; /* Legacy weak MspInit */ |
| break; |
| |
| case HAL_JPEG_MSPDEINIT_CB_ID : |
| hjpeg->MspDeInitCallback = HAL_JPEG_MspDeInit; /* Legacy weak MspInit */ |
| break; |
| |
| default : |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hjpeg); |
| return status; |
| } |
| |
| /** |
| * @brief Register Info Ready JPEG Callback |
| * To be used instead of the weak HAL_JPEG_InfoReadyCallback() predefined callback |
| * @param hjpeg JPEG handle |
| * @param pCallback pointer to the Info Ready Callback function |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_RegisterInfoReadyCallback(JPEG_HandleTypeDef *hjpeg, |
| pJPEG_InfoReadyCallbackTypeDef pCallback) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if (pCallback == NULL) |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| return HAL_ERROR; |
| } |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (HAL_JPEG_STATE_READY == hjpeg->State) |
| { |
| hjpeg->InfoReadyCallback = pCallback; |
| } |
| else |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hjpeg); |
| return status; |
| } |
| |
| /** |
| * @brief UnRegister the Info Ready JPEG Callback |
| * Info Ready JPEG Callback is redirected to the weak HAL_JPEG_InfoReadyCallback() predefined callback |
| * @param hjpeg JPEG handle |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_UnRegisterInfoReadyCallback(JPEG_HandleTypeDef *hjpeg) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (HAL_JPEG_STATE_READY == hjpeg->State) |
| { |
| hjpeg->InfoReadyCallback = HAL_JPEG_InfoReadyCallback; /* Legacy weak InfoReadyCallback */ |
| } |
| else |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hjpeg); |
| return status; |
| } |
| |
| /** |
| * @brief Register Get Data JPEG Callback |
| * To be used instead of the weak HAL_JPEG_GetDataCallback() predefined callback |
| * @param hjpeg JPEG handle |
| * @param pCallback pointer to the Get Data Callback function |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_RegisterGetDataCallback(JPEG_HandleTypeDef *hjpeg, pJPEG_GetDataCallbackTypeDef pCallback) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if (pCallback == NULL) |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| return HAL_ERROR; |
| } |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (HAL_JPEG_STATE_READY == hjpeg->State) |
| { |
| hjpeg->GetDataCallback = pCallback; |
| } |
| else |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hjpeg); |
| return status; |
| } |
| |
| /** |
| * @brief UnRegister the Get Data JPEG Callback |
| * Get Data JPEG Callback is redirected to the weak HAL_JPEG_GetDataCallback() predefined callback |
| * @param hjpeg JPEG handle |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_UnRegisterGetDataCallback(JPEG_HandleTypeDef *hjpeg) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (HAL_JPEG_STATE_READY == hjpeg->State) |
| { |
| hjpeg->GetDataCallback = HAL_JPEG_GetDataCallback; /* Legacy weak GetDataCallback */ |
| } |
| else |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hjpeg); |
| return status; |
| } |
| |
| /** |
| * @brief Register Data Ready JPEG Callback |
| * To be used instead of the weak HAL_JPEG_DataReadyCallback() predefined callback |
| * @param hjpeg JPEG handle |
| * @param pCallback pointer to the Get Data Callback function |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_RegisterDataReadyCallback(JPEG_HandleTypeDef *hjpeg, |
| pJPEG_DataReadyCallbackTypeDef pCallback) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if (pCallback == NULL) |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| return HAL_ERROR; |
| } |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (HAL_JPEG_STATE_READY == hjpeg->State) |
| { |
| hjpeg->DataReadyCallback = pCallback; |
| } |
| else |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hjpeg); |
| return status; |
| } |
| |
| /** |
| * @brief UnRegister the Data Ready JPEG Callback |
| * Get Data Ready Callback is redirected to the weak HAL_JPEG_DataReadyCallback() predefined callback |
| * @param hjpeg JPEG handle |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_UnRegisterDataReadyCallback(JPEG_HandleTypeDef *hjpeg) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (HAL_JPEG_STATE_READY == hjpeg->State) |
| { |
| hjpeg->DataReadyCallback = HAL_JPEG_DataReadyCallback; /* Legacy weak DataReadyCallback */ |
| } |
| else |
| { |
| /* Update the error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hjpeg); |
| return status; |
| } |
| |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup JPEG_Exported_Functions_Group2 Configuration functions |
| * @brief JPEG Configuration functions. |
| * |
| @verbatim |
| ============================================================================== |
| ##### Configuration functions ##### |
| ============================================================================== |
| [..] This section provides functions allowing to: |
| (+) HAL_JPEG_ConfigEncoding() : JPEG encoding configuration |
| (+) HAL_JPEG_GetInfo() : Extract the image configuration from the JPEG header during the decoding |
| (+) HAL_JPEG_EnableHeaderParsing() : Enable JPEG Header parsing for decoding |
| (+) HAL_JPEG_DisableHeaderParsing() : Disable JPEG Header parsing for decoding |
| (+) HAL_JPEG_SetUserQuantTables : Modify the default Quantization tables used for JPEG encoding. |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Set the JPEG encoding configuration. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pConf pointer to a JPEG_ConfTypeDef structure that contains |
| * the encoding configuration |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_ConfigEncoding(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pConf) |
| { |
| uint32_t error; |
| uint32_t numberMCU; |
| uint32_t hfactor; |
| uint32_t vfactor; |
| uint32_t hMCU; |
| uint32_t vMCU; |
| |
| /* Check the JPEG handle allocation */ |
| if ((hjpeg == NULL) || (pConf == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| else |
| { |
| /* Check the parameters */ |
| assert_param(IS_JPEG_COLORSPACE(pConf->ColorSpace)); |
| assert_param(IS_JPEG_CHROMASUBSAMPLING(pConf->ChromaSubsampling)); |
| assert_param(IS_JPEG_IMAGE_QUALITY(pConf->ImageQuality)); |
| |
| /* Process Locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (hjpeg->State == HAL_JPEG_STATE_READY) |
| { |
| hjpeg->State = HAL_JPEG_STATE_BUSY; |
| |
| hjpeg->Conf.ColorSpace = pConf->ColorSpace; |
| hjpeg->Conf.ChromaSubsampling = pConf->ChromaSubsampling; |
| hjpeg->Conf.ImageHeight = pConf->ImageHeight; |
| hjpeg->Conf.ImageWidth = pConf->ImageWidth; |
| hjpeg->Conf.ImageQuality = pConf->ImageQuality; |
| |
| /* Reset the Color Space : by default only one quantization table is used*/ |
| hjpeg->Instance->CONFR1 &= ~JPEG_CONFR1_COLORSPACE; |
| |
| /* Set Number of color components*/ |
| if (hjpeg->Conf.ColorSpace == JPEG_GRAYSCALE_COLORSPACE) |
| { |
| /*Gray Scale is only one component 8x8 blocks i.e 4:4:4*/ |
| hjpeg->Conf.ChromaSubsampling = JPEG_444_SUBSAMPLING; |
| |
| JPEG_SetColorGrayScale(hjpeg); |
| /* Set quantization table 0*/ |
| error = JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable0, (hjpeg->Instance->QMEM0)); |
| } |
| else if (hjpeg->Conf.ColorSpace == JPEG_YCBCR_COLORSPACE) |
| { |
| /* |
| Set the Color Space for YCbCr : 2 quantization tables are used |
| one for Luminance(Y) and one for both Chrominances (Cb & Cr) |
| */ |
| hjpeg->Instance->CONFR1 |= JPEG_CONFR1_COLORSPACE_0; |
| |
| JPEG_SetColorYCBCR(hjpeg); |
| |
| /* Set quantization table 0*/ |
| error = JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable0, (hjpeg->Instance->QMEM0)); |
| /*By default quantization table 0 for component 0 and quantization table 1 for both components 1 and 2*/ |
| error |= JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable1, (hjpeg->Instance->QMEM1)); |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_CUSTOM_TABLES) != 0UL) |
| { |
| /*Use user customized quantization tables , 1 table per component*/ |
| /* use 3 quantization tables , one for each component*/ |
| hjpeg->Instance->CONFR1 &= (~JPEG_CONFR1_COLORSPACE); |
| hjpeg->Instance->CONFR1 |= JPEG_CONFR1_COLORSPACE_1; |
| |
| error |= JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable2, (hjpeg->Instance->QMEM2)); |
| |
| /*Use Quantization 1 table for component 1*/ |
| hjpeg->Instance->CONFR5 &= (~JPEG_CONFR5_QT); |
| hjpeg->Instance->CONFR5 |= JPEG_CONFR5_QT_0; |
| |
| /*Use Quantization 2 table for component 2*/ |
| hjpeg->Instance->CONFR6 &= (~JPEG_CONFR6_QT); |
| hjpeg->Instance->CONFR6 |= JPEG_CONFR6_QT_1; |
| } |
| } |
| else /* ColorSpace == JPEG_CMYK_COLORSPACE */ |
| { |
| JPEG_SetColorCMYK(hjpeg); |
| |
| /* Set quantization table 0*/ |
| error = JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable0, (hjpeg->Instance->QMEM0)); |
| /*By default quantization table 0 for All components*/ |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_CUSTOM_TABLES) != 0UL) |
| { |
| /*Use user customized quantization tables , 1 table per component*/ |
| /* use 4 quantization tables , one for each component*/ |
| hjpeg->Instance->CONFR1 |= JPEG_CONFR1_COLORSPACE; |
| |
| error |= JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable1, (hjpeg->Instance->QMEM1)); |
| error |= JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable2, (hjpeg->Instance->QMEM2)); |
| error |= JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable3, (hjpeg->Instance->QMEM3)); |
| |
| /*Use Quantization 1 table for component 1*/ |
| hjpeg->Instance->CONFR5 |= JPEG_CONFR5_QT_0; |
| |
| /*Use Quantization 2 table for component 2*/ |
| hjpeg->Instance->CONFR6 |= JPEG_CONFR6_QT_1; |
| |
| /*Use Quantization 3 table for component 3*/ |
| hjpeg->Instance->CONFR7 |= JPEG_CONFR7_QT; |
| } |
| } |
| |
| if (error != 0UL) |
| { |
| hjpeg->ErrorCode = HAL_JPEG_ERROR_QUANT_TABLE; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Set the JPEG State to ready */ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| return HAL_ERROR; |
| } |
| /* Set the image size*/ |
| /* set the number of lines*/ |
| MODIFY_REG(hjpeg->Instance->CONFR1, JPEG_CONFR1_YSIZE, ((hjpeg->Conf.ImageHeight & 0x0000FFFFUL) << 16)); |
| /* set the number of pixels per line*/ |
| MODIFY_REG(hjpeg->Instance->CONFR3, JPEG_CONFR3_XSIZE, ((hjpeg->Conf.ImageWidth & 0x0000FFFFUL) << 16)); |
| |
| |
| if (hjpeg->Conf.ChromaSubsampling == JPEG_420_SUBSAMPLING) /* 4:2:0*/ |
| { |
| hfactor = 16; |
| vfactor = 16; |
| } |
| else if (hjpeg->Conf.ChromaSubsampling == JPEG_422_SUBSAMPLING) /* 4:2:2*/ |
| { |
| hfactor = 16; |
| vfactor = 8; |
| } |
| else /* Default is 8x8 MCU, 4:4:4*/ |
| { |
| hfactor = 8; |
| vfactor = 8; |
| } |
| |
| hMCU = (hjpeg->Conf.ImageWidth / hfactor); |
| if ((hjpeg->Conf.ImageWidth % hfactor) != 0UL) |
| { |
| hMCU++; /*+1 for horizontal incomplete MCU */ |
| } |
| |
| vMCU = (hjpeg->Conf.ImageHeight / vfactor); |
| if ((hjpeg->Conf.ImageHeight % vfactor) != 0UL) |
| { |
| vMCU++; /*+1 for vertical incomplete MCU */ |
| } |
| |
| numberMCU = (hMCU * vMCU) - 1UL; /* Bit Field JPEG_CONFR2_NMCU shall be set to NB_MCU - 1*/ |
| /* Set the number of MCU*/ |
| hjpeg->Instance->CONFR2 = (numberMCU & JPEG_CONFR2_NMCU); |
| |
| hjpeg->Context |= JPEG_CONTEXT_CONF_ENCODING; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Set the JPEG State to ready */ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| else |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Return function status */ |
| return HAL_BUSY; |
| } |
| } |
| } |
| |
| /** |
| * @brief Extract the image configuration from the JPEG header during the decoding |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pInfo pointer to a JPEG_ConfTypeDef structure that contains |
| * The JPEG decoded header information |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_GetInfo(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo) |
| { |
| uint32_t yblockNb; |
| uint32_t cBblockNb; |
| uint32_t cRblockNb; |
| |
| /* Check the JPEG handle allocation */ |
| if ((hjpeg == NULL) || (pInfo == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| |
| /*Read the conf parameters */ |
| if ((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == JPEG_CONFR1_NF_1) |
| { |
| pInfo->ColorSpace = JPEG_YCBCR_COLORSPACE; |
| } |
| else if ((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == 0UL) |
| { |
| pInfo->ColorSpace = JPEG_GRAYSCALE_COLORSPACE; |
| } |
| else if ((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == JPEG_CONFR1_NF) |
| { |
| pInfo->ColorSpace = JPEG_CMYK_COLORSPACE; |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| pInfo->ImageHeight = (hjpeg->Instance->CONFR1 & 0xFFFF0000UL) >> 16; |
| pInfo->ImageWidth = (hjpeg->Instance->CONFR3 & 0xFFFF0000UL) >> 16; |
| |
| if ((pInfo->ColorSpace == JPEG_YCBCR_COLORSPACE) || (pInfo->ColorSpace == JPEG_CMYK_COLORSPACE)) |
| { |
| yblockNb = (hjpeg->Instance->CONFR4 & JPEG_CONFR4_NB) >> 4; |
| cBblockNb = (hjpeg->Instance->CONFR5 & JPEG_CONFR5_NB) >> 4; |
| cRblockNb = (hjpeg->Instance->CONFR6 & JPEG_CONFR6_NB) >> 4; |
| |
| if ((yblockNb == 1UL) && (cBblockNb == 0UL) && (cRblockNb == 0UL)) |
| { |
| pInfo->ChromaSubsampling = JPEG_422_SUBSAMPLING; /*16x8 block*/ |
| } |
| else if ((yblockNb == 0UL) && (cBblockNb == 0UL) && (cRblockNb == 0UL)) |
| { |
| pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; |
| } |
| else if ((yblockNb == 3UL) && (cBblockNb == 0UL) && (cRblockNb == 0UL)) |
| { |
| pInfo->ChromaSubsampling = JPEG_420_SUBSAMPLING; |
| } |
| else /*Default is 4:4:4*/ |
| { |
| pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; |
| } |
| } |
| else |
| { |
| pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; |
| } |
| |
| pInfo->ImageQuality = JPEG_GetQuality(hjpeg); |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Enable JPEG Header parsing for decoding |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for the JPEG. |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_EnableHeaderParsing(JPEG_HandleTypeDef *hjpeg) |
| { |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (hjpeg->State == HAL_JPEG_STATE_READY) |
| { |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_BUSY; |
| |
| /* Enable header processing*/ |
| hjpeg->Instance->CONFR1 |= JPEG_CONFR1_HDR; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| return HAL_OK; |
| } |
| else |
| { |
| /* Process unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_BUSY; |
| } |
| } |
| |
| /** |
| * @brief Disable JPEG Header parsing for decoding |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for the JPEG. |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_DisableHeaderParsing(JPEG_HandleTypeDef *hjpeg) |
| { |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (hjpeg->State == HAL_JPEG_STATE_READY) |
| { |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_BUSY; |
| |
| /* Disable header processing*/ |
| hjpeg->Instance->CONFR1 &= ~JPEG_CONFR1_HDR; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| return HAL_OK; |
| } |
| else |
| { |
| /* Process unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_BUSY; |
| } |
| } |
| |
| /** |
| * @brief Modify the default Quantization tables used for JPEG encoding. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param QTable0 pointer to uint8_t , define the user quantification table for color component 1. |
| * If NULL assume no need to update the table and no error return |
| * @param QTable1 pointer to uint8_t , define the user quantification table for color component 2. |
| * If NULL assume no need to update the table and no error return. |
| * @param QTable2 pointer to uint8_t , define the user quantification table for color component 3, |
| * If NULL assume no need to update the table and no error return. |
| * @param QTable3 pointer to uint8_t , define the user quantification table for color component 4. |
| * If NULL assume no need to update the table and no error return. |
| * |
| * @retval HAL status |
| */ |
| |
| |
| HAL_StatusTypeDef HAL_JPEG_SetUserQuantTables(JPEG_HandleTypeDef *hjpeg, uint8_t *QTable0, uint8_t *QTable1, |
| uint8_t *QTable2, uint8_t *QTable3) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (hjpeg->State == HAL_JPEG_STATE_READY) |
| { |
| /* Change the DMA state */ |
| hjpeg->State = HAL_JPEG_STATE_BUSY; |
| |
| hjpeg->Context |= JPEG_CONTEXT_CUSTOM_TABLES; |
| |
| hjpeg->QuantTable0 = QTable0; |
| hjpeg->QuantTable1 = QTable1; |
| hjpeg->QuantTable2 = QTable2; |
| hjpeg->QuantTable3 = QTable3; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Change the DMA state */ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| else |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_BUSY; |
| } |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup JPEG_Exported_Functions_Group3 encoding/decoding processing functions |
| * @brief processing functions. |
| * |
| @verbatim |
| ============================================================================== |
| ##### JPEG processing functions ##### |
| ============================================================================== |
| [..] This section provides functions allowing to: |
| (+) HAL_JPEG_Encode() : JPEG encoding with polling process |
| (+) HAL_JPEG_Decode() : JPEG decoding with polling process |
| (+) HAL_JPEG_Encode_IT() : JPEG encoding with interrupt process |
| (+) HAL_JPEG_Decode_IT() : JPEG decoding with interrupt process |
| (+) HAL_JPEG_Encode_DMA() : JPEG encoding with DMA process |
| (+) HAL_JPEG_Decode_DMA() : JPEG decoding with DMA process |
| (+) HAL_JPEG_Pause() : Pause the Input/Output processing |
| (+) HAL_JPEG_Resume() : Resume the JPEG Input/Output processing |
| (+) HAL_JPEG_ConfigInputBuffer() : Config Encoding/Decoding Input Buffer |
| (+) HAL_JPEG_ConfigOutputBuffer() : Config Encoding/Decoding Output Buffer |
| (+) HAL_JPEG_Abort() : Aborts the JPEG Encoding/Decoding |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Starts JPEG encoding with polling processing |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pDataInMCU Pointer to the Input buffer |
| * @param InDataLength size in bytes Input buffer |
| * @param pDataOut Pointer to the jpeg output data buffer |
| * @param OutDataLength size in bytes of the Output buffer |
| * @param Timeout Specify Timeout value |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Encode(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, |
| uint8_t *pDataOut, uint32_t OutDataLength, uint32_t Timeout) |
| { |
| uint32_t tickstart; |
| |
| /* Check the parameters */ |
| assert_param((InDataLength >= 4UL)); |
| assert_param((OutDataLength >= 4UL)); |
| |
| /* Check In/out buffer allocation and size */ |
| if ((hjpeg == NULL) || (pDataInMCU == NULL) || (pDataOut == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| /* Process locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (hjpeg->State != HAL_JPEG_STATE_READY) |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_BUSY; |
| } |
| |
| if (hjpeg->State == HAL_JPEG_STATE_READY) |
| { |
| if ((hjpeg->Context & JPEG_CONTEXT_CONF_ENCODING) == JPEG_CONTEXT_CONF_ENCODING) |
| { |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_BUSY_ENCODING; |
| |
| /*Set the Context to Encode with Polling*/ |
| hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); |
| hjpeg->Context |= (JPEG_CONTEXT_ENCODE | JPEG_CONTEXT_POLLING); |
| |
| /* Get tick */ |
| tickstart = HAL_GetTick(); |
| |
| /*Store In/out buffers pointers and size*/ |
| hjpeg->pJpegInBuffPtr = pDataInMCU; |
| hjpeg->pJpegOutBuffPtr = pDataOut; |
| hjpeg->InDataLength = InDataLength - (InDataLength % 4UL); /* In Data length must be multiple of 4 Bytes (1 word)*/ |
| hjpeg->OutDataLength = OutDataLength - (OutDataLength % 4UL); /* Out Data length must be multiple of 4 Bytes (1 word)*/ |
| |
| /*Reset In/out data counter */ |
| hjpeg->JpegInCount = 0; |
| hjpeg->JpegOutCount = 0; |
| |
| /*Init decoding process*/ |
| JPEG_Init_Process(hjpeg); |
| |
| /*JPEG data processing : In/Out FIFO transfer*/ |
| while ((JPEG_Process(hjpeg) == JPEG_PROCESS_ONGOING)) |
| { |
| if (Timeout != HAL_MAX_DELAY) |
| { |
| if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) |
| { |
| |
| /* Update error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_TIMEOUT; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| return HAL_TIMEOUT; |
| } |
| } |
| } |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| } |
| else |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_ERROR; |
| } |
| } |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Starts JPEG decoding with polling processing |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pDataIn Pointer to the input data buffer |
| * @param InDataLength size in bytes Input buffer |
| * @param pDataOutMCU Pointer to the Output data buffer |
| * @param OutDataLength size in bytes of the Output buffer |
| * @param Timeout Specify Timeout value |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Decode(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataIn, uint32_t InDataLength, |
| uint8_t *pDataOutMCU, uint32_t OutDataLength, uint32_t Timeout) |
| { |
| uint32_t tickstart; |
| |
| /* Check the parameters */ |
| assert_param((InDataLength >= 4UL)); |
| assert_param((OutDataLength >= 4UL)); |
| |
| /* Check In/out buffer allocation and size */ |
| if ((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Process Locked */ |
| __HAL_LOCK(hjpeg); |
| |
| /* Get tick */ |
| tickstart = HAL_GetTick(); |
| |
| if (hjpeg->State == HAL_JPEG_STATE_READY) |
| { |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_BUSY_DECODING; |
| |
| /*Set the Context to Decode with Polling*/ |
| /*Set the Context to Encode with Polling*/ |
| hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); |
| hjpeg->Context |= (JPEG_CONTEXT_DECODE | JPEG_CONTEXT_POLLING); |
| |
| /*Store In/out buffers pointers and size*/ |
| hjpeg->pJpegInBuffPtr = pDataIn; |
| hjpeg->pJpegOutBuffPtr = pDataOutMCU; |
| hjpeg->InDataLength = InDataLength - (InDataLength % 4UL); /*In Data length must be multiple of 4 Bytes (1 word)*/ |
| hjpeg->OutDataLength = OutDataLength - (OutDataLength % 4UL); /*Out Data length must be multiple of 4 Bytes (1 word)*/ |
| |
| /*Reset In/out data counter */ |
| hjpeg->JpegInCount = 0; |
| hjpeg->JpegOutCount = 0; |
| |
| /*Init decoding process*/ |
| JPEG_Init_Process(hjpeg); |
| |
| /*JPEG data processing : In/Out FIFO transfer*/ |
| while ((JPEG_Process(hjpeg) == JPEG_PROCESS_ONGOING)) |
| { |
| if (Timeout != HAL_MAX_DELAY) |
| { |
| if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) |
| { |
| |
| /* Update error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_TIMEOUT; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| return HAL_TIMEOUT; |
| } |
| } |
| } |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| } |
| else |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_BUSY; |
| } |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Starts JPEG encoding with interrupt processing |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pDataInMCU Pointer to the Input buffer |
| * @param InDataLength size in bytes Input buffer |
| * @param pDataOut Pointer to the jpeg output data buffer |
| * @param OutDataLength size in bytes of the Output buffer |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Encode_IT(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, |
| uint8_t *pDataOut, uint32_t OutDataLength) |
| { |
| /* Check the parameters */ |
| assert_param((InDataLength >= 4UL)); |
| assert_param((OutDataLength >= 4UL)); |
| |
| /* Check In/out buffer allocation and size */ |
| if ((hjpeg == NULL) || (pDataInMCU == NULL) || (pDataOut == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Process Locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (hjpeg->State != HAL_JPEG_STATE_READY) |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_BUSY; |
| } |
| else |
| { |
| if ((hjpeg->Context & JPEG_CONTEXT_CONF_ENCODING) == JPEG_CONTEXT_CONF_ENCODING) |
| { |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_BUSY_ENCODING; |
| |
| /*Set the Context to Encode with IT*/ |
| hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); |
| hjpeg->Context |= (JPEG_CONTEXT_ENCODE | JPEG_CONTEXT_IT); |
| |
| /*Store In/out buffers pointers and size*/ |
| hjpeg->pJpegInBuffPtr = pDataInMCU; |
| hjpeg->pJpegOutBuffPtr = pDataOut; |
| hjpeg->InDataLength = InDataLength - (InDataLength % 4UL); /*In Data length must be multiple of 4 Bytes (1 word)*/ |
| hjpeg->OutDataLength = OutDataLength - (OutDataLength % 4UL); /*Out Data length must be multiple of 4 Bytes (1 word)*/ |
| |
| /*Reset In/out data counter */ |
| hjpeg->JpegInCount = 0; |
| hjpeg->JpegOutCount = 0; |
| |
| /*Init decoding process*/ |
| JPEG_Init_Process(hjpeg); |
| |
| } |
| else |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_ERROR; |
| } |
| } |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Starts JPEG decoding with interrupt processing |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pDataIn Pointer to the input data buffer |
| * @param InDataLength size in bytes Input buffer |
| * @param pDataOutMCU Pointer to the Output data buffer |
| * @param OutDataLength size in bytes of the Output buffer |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Decode_IT(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataIn, uint32_t InDataLength, |
| uint8_t *pDataOutMCU, uint32_t OutDataLength) |
| { |
| /* Check the parameters */ |
| assert_param((InDataLength >= 4UL)); |
| assert_param((OutDataLength >= 4UL)); |
| |
| /* Check In/out buffer allocation and size */ |
| if ((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Process Locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (hjpeg->State == HAL_JPEG_STATE_READY) |
| { |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_BUSY_DECODING; |
| |
| /*Set the Context to Decode with IT*/ |
| hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); |
| hjpeg->Context |= (JPEG_CONTEXT_DECODE | JPEG_CONTEXT_IT); |
| |
| /*Store In/out buffers pointers and size*/ |
| hjpeg->pJpegInBuffPtr = pDataIn; |
| hjpeg->pJpegOutBuffPtr = pDataOutMCU; |
| hjpeg->InDataLength = InDataLength - (InDataLength % 4UL); /*In Data length must be multiple of 4 Bytes (1 word)*/ |
| hjpeg->OutDataLength = OutDataLength - (OutDataLength % 4UL); /*Out Data length must be multiple of 4 Bytes (1 word)*/ |
| |
| /*Reset In/out data counter */ |
| hjpeg->JpegInCount = 0; |
| hjpeg->JpegOutCount = 0; |
| |
| /*Init decoding process*/ |
| JPEG_Init_Process(hjpeg); |
| |
| } |
| else |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_BUSY; |
| } |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Starts JPEG encoding with DMA processing |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pDataInMCU Pointer to the Input buffer |
| * @param InDataLength size in bytes Input buffer |
| * @param pDataOut Pointer to the jpeg output data buffer |
| * @param OutDataLength size in bytes of the Output buffer |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Encode_DMA(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, |
| uint8_t *pDataOut, uint32_t OutDataLength) |
| { |
| /* Check the parameters */ |
| assert_param((InDataLength >= 4UL)); |
| assert_param((OutDataLength >= 4UL)); |
| |
| /* Check In/out buffer allocation and size */ |
| if ((hjpeg == NULL) || (pDataInMCU == NULL) || (pDataOut == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Process Locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (hjpeg->State != HAL_JPEG_STATE_READY) |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_BUSY; |
| } |
| else |
| { |
| if ((hjpeg->Context & JPEG_CONTEXT_CONF_ENCODING) == JPEG_CONTEXT_CONF_ENCODING) |
| { |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_BUSY_ENCODING; |
| |
| /*Set the Context to Encode with DMA*/ |
| hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); |
| hjpeg->Context |= (JPEG_CONTEXT_ENCODE | JPEG_CONTEXT_DMA); |
| |
| /*Store In/out buffers pointers and size*/ |
| hjpeg->pJpegInBuffPtr = pDataInMCU; |
| hjpeg->pJpegOutBuffPtr = pDataOut; |
| hjpeg->InDataLength = InDataLength; |
| hjpeg->OutDataLength = OutDataLength; |
| |
| /*Reset In/out data counter */ |
| hjpeg->JpegInCount = 0; |
| hjpeg->JpegOutCount = 0; |
| |
| /*Init decoding process*/ |
| JPEG_Init_Process(hjpeg); |
| |
| /* JPEG encoding process using DMA */ |
| if (JPEG_DMA_StartProcess(hjpeg) != HAL_OK) |
| { |
| /* Update State */ |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_ERROR; |
| } |
| |
| } |
| else |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_ERROR; |
| } |
| } |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Starts JPEG decoding with DMA processing |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pDataIn Pointer to the input data buffer |
| * @param InDataLength size in bytes Input buffer |
| * @param pDataOutMCU Pointer to the Output data buffer |
| * @param OutDataLength size in bytes of the Output buffer |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Decode_DMA(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataIn, uint32_t InDataLength, |
| uint8_t *pDataOutMCU, uint32_t OutDataLength) |
| { |
| /* Check the parameters */ |
| assert_param((InDataLength >= 4UL)); |
| assert_param((OutDataLength >= 4UL)); |
| |
| /* Check In/out buffer allocation and size */ |
| if ((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Process Locked */ |
| __HAL_LOCK(hjpeg); |
| |
| if (hjpeg->State == HAL_JPEG_STATE_READY) |
| { |
| /*Change JPEG state*/ |
| hjpeg->State = HAL_JPEG_STATE_BUSY_DECODING; |
| |
| /*Set the Context to Decode with DMA*/ |
| hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); |
| hjpeg->Context |= (JPEG_CONTEXT_DECODE | JPEG_CONTEXT_DMA); |
| |
| /*Store In/out buffers pointers and size*/ |
| hjpeg->pJpegInBuffPtr = pDataIn; |
| hjpeg->pJpegOutBuffPtr = pDataOutMCU; |
| hjpeg->InDataLength = InDataLength; |
| hjpeg->OutDataLength = OutDataLength; |
| |
| /*Reset In/out data counter */ |
| hjpeg->JpegInCount = 0; |
| hjpeg->JpegOutCount = 0; |
| |
| /*Init decoding process*/ |
| JPEG_Init_Process(hjpeg); |
| |
| /* JPEG decoding process using DMA */ |
| if (JPEG_DMA_StartProcess(hjpeg) != HAL_OK) |
| { |
| /* Update State */ |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_ERROR; |
| } |
| } |
| else |
| { |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| return HAL_BUSY; |
| } |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Pause the JPEG Input/Output processing |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param XferSelection This parameter can be one of the following values : |
| * JPEG_PAUSE_RESUME_INPUT : Pause Input processing |
| * JPEG_PAUSE_RESUME_OUTPUT: Pause Output processing |
| * JPEG_PAUSE_RESUME_INPUT_OUTPUT: Pause Input and Output processing |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Pause(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection) |
| { |
| uint32_t mask = 0; |
| |
| assert_param(IS_JPEG_PAUSE_RESUME_STATE(XferSelection)); |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) |
| { |
| if ((XferSelection & JPEG_PAUSE_RESUME_INPUT) == JPEG_PAUSE_RESUME_INPUT) |
| { |
| hjpeg->Context |= JPEG_CONTEXT_PAUSE_INPUT; |
| } |
| if ((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) |
| { |
| hjpeg->Context |= JPEG_CONTEXT_PAUSE_OUTPUT; |
| } |
| |
| } |
| else if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) |
| { |
| |
| if ((XferSelection & JPEG_PAUSE_RESUME_INPUT) == JPEG_PAUSE_RESUME_INPUT) |
| { |
| hjpeg->Context |= JPEG_CONTEXT_PAUSE_INPUT; |
| mask |= (JPEG_IT_IFT | JPEG_IT_IFNF); |
| } |
| if ((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) |
| { |
| hjpeg->Context |= JPEG_CONTEXT_PAUSE_OUTPUT; |
| mask |= (JPEG_IT_OFT | JPEG_IT_OFNE | JPEG_IT_EOC); |
| } |
| __HAL_JPEG_DISABLE_IT(hjpeg, mask); |
| |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Resume the JPEG Input/Output processing |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param XferSelection This parameter can be one of the following values : |
| * JPEG_PAUSE_RESUME_INPUT : Resume Input processing |
| * JPEG_PAUSE_RESUME_OUTPUT: Resume Output processing |
| * JPEG_PAUSE_RESUME_INPUT_OUTPUT: Resume Input and Output processing |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Resume(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection) |
| { |
| uint32_t mask = 0; |
| uint32_t xfrSize; |
| |
| assert_param(IS_JPEG_PAUSE_RESUME_STATE(XferSelection)); |
| |
| if ((hjpeg->Context & (JPEG_CONTEXT_PAUSE_INPUT | JPEG_CONTEXT_PAUSE_OUTPUT)) == 0UL) |
| { |
| /* if nothing paused to resume return error*/ |
| return HAL_ERROR; |
| } |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) |
| { |
| |
| if ((XferSelection & JPEG_PAUSE_RESUME_INPUT) == JPEG_PAUSE_RESUME_INPUT) |
| { |
| hjpeg->Context &= (~JPEG_CONTEXT_PAUSE_INPUT); |
| /*if the MDMA In is triggred with JPEG In FIFO Threshold flag |
| then MDMA In buffer size is 32 bytes |
| |
| else (MDMA In is triggred with JPEG In FIFO not full flag) |
| then MDMA In buffer size is 4 bytes |
| */ |
| xfrSize = hjpeg->hdmain->Init.BufferTransferLength; |
| |
| if (xfrSize == 0UL) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| return HAL_ERROR; |
| } |
| /*MDMA transfer size (BNDTR) must be a multiple of MDMA buffer size (TLEN)*/ |
| hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % xfrSize); |
| |
| |
| if (hjpeg->InDataLength > 0UL) |
| { |
| /* Start DMA FIFO In transfer */ |
| if (HAL_MDMA_Start_IT(hjpeg->hdmain, (uint32_t)hjpeg->pJpegInBuffPtr, (uint32_t)&hjpeg->Instance->DIR, |
| hjpeg->InDataLength, 1) != HAL_OK) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| return HAL_ERROR; |
| } |
| } |
| } |
| if ((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) |
| { |
| hjpeg->Context &= (~JPEG_CONTEXT_PAUSE_OUTPUT); |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_ENDING_DMA) != 0UL) |
| { |
| JPEG_DMA_PollResidualData(hjpeg); |
| } |
| else |
| { |
| /*if the MDMA Out is triggred with JPEG Out FIFO Threshold flag |
| then MDMA out buffer size is 32 bytes |
| else (MDMA Out is triggred with JPEG Out FIFO not empty flag) |
| then MDMA buffer size is 4 bytes |
| */ |
| xfrSize = hjpeg->hdmaout->Init.BufferTransferLength; |
| |
| if (xfrSize == 0UL) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| return HAL_ERROR; |
| } |
| /*MDMA transfer size (BNDTR) must be a multiple of MDMA buffer size (TLEN)*/ |
| hjpeg->OutDataLength = hjpeg->OutDataLength - (hjpeg->OutDataLength % xfrSize); |
| |
| /* Start DMA FIFO Out transfer */ |
| if (HAL_MDMA_Start_IT(hjpeg->hdmaout, (uint32_t)&hjpeg->Instance->DOR, (uint32_t)hjpeg->pJpegOutBuffPtr, |
| hjpeg->OutDataLength, 1) != HAL_OK) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| return HAL_ERROR; |
| } |
| } |
| |
| } |
| |
| } |
| else if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) |
| { |
| if ((XferSelection & JPEG_PAUSE_RESUME_INPUT) == JPEG_PAUSE_RESUME_INPUT) |
| { |
| hjpeg->Context &= (~JPEG_CONTEXT_PAUSE_INPUT); |
| mask |= (JPEG_IT_IFT | JPEG_IT_IFNF); |
| } |
| if ((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) |
| { |
| hjpeg->Context &= (~JPEG_CONTEXT_PAUSE_OUTPUT); |
| mask |= (JPEG_IT_OFT | JPEG_IT_OFNE | JPEG_IT_EOC); |
| } |
| __HAL_JPEG_ENABLE_IT(hjpeg, mask); |
| |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Config Encoding/Decoding Input Buffer. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module. |
| * @param pNewInputBuffer Pointer to the new input data buffer |
| * @param InDataLength Size in bytes of the new Input data buffer |
| * @retval HAL status |
| */ |
| void HAL_JPEG_ConfigInputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewInputBuffer, uint32_t InDataLength) |
| { |
| hjpeg->pJpegInBuffPtr = pNewInputBuffer; |
| hjpeg->InDataLength = InDataLength; |
| } |
| |
| /** |
| * @brief Config Encoding/Decoding Output Buffer. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module. |
| * @param pNewOutputBuffer Pointer to the new output data buffer |
| * @param OutDataLength Size in bytes of the new Output data buffer |
| * @retval HAL status |
| */ |
| void HAL_JPEG_ConfigOutputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewOutputBuffer, uint32_t OutDataLength) |
| { |
| hjpeg->pJpegOutBuffPtr = pNewOutputBuffer; |
| hjpeg->OutDataLength = OutDataLength; |
| } |
| |
| /** |
| * @brief Aborts the JPEG Encoding/Decoding. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_JPEG_Abort(JPEG_HandleTypeDef *hjpeg) |
| { |
| uint32_t tickstart; |
| uint32_t tmpContext; |
| tmpContext = hjpeg->Context; |
| |
| /*Reset the Context operation and method*/ |
| hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK | JPEG_CONTEXT_ENDING_DMA); |
| |
| if ((tmpContext & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) |
| { |
| /* Stop the DMA In/out Xfer*/ |
| if (HAL_MDMA_Abort(hjpeg->hdmaout) != HAL_OK) |
| { |
| if (hjpeg->hdmaout->ErrorCode == HAL_MDMA_ERROR_TIMEOUT) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| } |
| } |
| if (HAL_MDMA_Abort(hjpeg->hdmain) != HAL_OK) |
| { |
| if (hjpeg->hdmain->ErrorCode == HAL_MDMA_ERROR_TIMEOUT) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| } |
| } |
| |
| } |
| |
| /* Stop the JPEG encoding/decoding process*/ |
| hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; |
| |
| /* Get tick */ |
| tickstart = HAL_GetTick(); |
| |
| /* Check if the JPEG Codec is effectively disabled */ |
| while (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_COF) != 0UL) |
| { |
| /* Check for the Timeout */ |
| if ((HAL_GetTick() - tickstart) > JPEG_TIMEOUT_VALUE) |
| { |
| /* Update error code */ |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_TIMEOUT; |
| |
| /* Change the DMA state */ |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| break; |
| } |
| } |
| |
| /* Disable All Interrupts */ |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); |
| |
| |
| /* Flush input and output FIFOs*/ |
| hjpeg->Instance->CR |= JPEG_CR_IFF; |
| hjpeg->Instance->CR |= JPEG_CR_OFF; |
| |
| /* Clear all flags */ |
| __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); |
| |
| /* Reset JpegInCount and JpegOutCount */ |
| hjpeg->JpegInCount = 0; |
| hjpeg->JpegOutCount = 0; |
| |
| /*Reset the Context Pause*/ |
| hjpeg->Context &= ~(JPEG_CONTEXT_PAUSE_INPUT | JPEG_CONTEXT_PAUSE_OUTPUT); |
| |
| /* Change the DMA state*/ |
| if (hjpeg->ErrorCode != HAL_JPEG_ERROR_NONE) |
| { |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| /* Return function status */ |
| return HAL_ERROR; |
| } |
| else |
| { |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| } |
| |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup JPEG_Exported_Functions_Group4 JPEG Decode/Encode callback functions |
| * @brief JPEG process callback functions. |
| * |
| @verbatim |
| ============================================================================== |
| ##### JPEG Decode and Encode callback functions ##### |
| ============================================================================== |
| [..] This section provides callback functions: |
| (+) HAL_JPEG_InfoReadyCallback() : Decoding JPEG Info ready callback |
| (+) HAL_JPEG_EncodeCpltCallback() : Encoding complete callback. |
| (+) HAL_JPEG_DecodeCpltCallback() : Decoding complete callback. |
| (+) HAL_JPEG_ErrorCallback() : JPEG error callback. |
| (+) HAL_JPEG_GetDataCallback() : Get New Data chunk callback. |
| (+) HAL_JPEG_DataReadyCallback() : Decoded/Encoded Data ready callback. |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Decoding JPEG Info ready callback. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pInfo pointer to a JPEG_ConfTypeDef structure that contains |
| * The JPEG decoded header information |
| * @retval None |
| */ |
| __weak void HAL_JPEG_InfoReadyCallback(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hjpeg); |
| UNUSED(pInfo); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_JPEG_HeaderParsingCpltCallback could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief Encoding complete callback. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| __weak void HAL_JPEG_EncodeCpltCallback(JPEG_HandleTypeDef *hjpeg) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hjpeg); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_JPEG_EncodeCpltCallback could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief Decoding complete callback. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| __weak void HAL_JPEG_DecodeCpltCallback(JPEG_HandleTypeDef *hjpeg) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hjpeg); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_JPEG_EncodeCpltCallback could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief JPEG error callback. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| __weak void HAL_JPEG_ErrorCallback(JPEG_HandleTypeDef *hjpeg) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hjpeg); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_JPEG_ErrorCallback could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief Get New Data chunk callback. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param NbDecodedData Number of consummed data in the previous chunk in bytes |
| * @retval None |
| */ |
| __weak void HAL_JPEG_GetDataCallback(JPEG_HandleTypeDef *hjpeg, uint32_t NbDecodedData) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hjpeg); |
| UNUSED(NbDecodedData); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_JPEG_GetDataCallback could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief Decoded/Encoded Data ready callback. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param pDataOut pointer to the output data buffer |
| * @param OutDataLength number in bytes of data available in the specified output buffer |
| * @retval None |
| */ |
| __weak void HAL_JPEG_DataReadyCallback(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataOut, uint32_t OutDataLength) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hjpeg); |
| UNUSED(pDataOut); |
| UNUSED(OutDataLength); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_JPEG_DataReadyCallback could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @} |
| */ |
| |
| |
| /** @defgroup JPEG_Exported_Functions_Group5 JPEG IRQ handler management |
| * @brief JPEG IRQ handler. |
| * |
| @verbatim |
| ============================================================================== |
| ##### JPEG IRQ handler management ##### |
| ============================================================================== |
| [..] This section provides JPEG IRQ handler function. |
| (+) HAL_JPEG_IRQHandler() : handles JPEG interrupt request |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief This function handles JPEG interrupt request. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| void HAL_JPEG_IRQHandler(JPEG_HandleTypeDef *hjpeg) |
| { |
| switch (hjpeg->State) |
| { |
| case HAL_JPEG_STATE_BUSY_ENCODING: |
| case HAL_JPEG_STATE_BUSY_DECODING: |
| /* continue JPEG data encoding/Decoding*/ |
| /* JPEG data processing : In/Out FIFO transfer*/ |
| if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) |
| { |
| (void) JPEG_Process(hjpeg); |
| } |
| else if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) |
| { |
| JPEG_DMA_ContinueProcess(hjpeg); |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup JPEG_Exported_Functions_Group6 Peripheral State functions |
| * @brief Peripheral State functions. |
| * |
| @verbatim |
| ============================================================================== |
| ##### Peripheral State and Error functions ##### |
| ============================================================================== |
| [..] This section provides JPEG State and Errors function. |
| (+) HAL_JPEG_GetState() : permits to get in run-time the JPEG state. |
| (+) HAL_JPEG_GetError() : Returns the JPEG error code if any. |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Returns the JPEG state. |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval JPEG state |
| */ |
| HAL_JPEG_STATETypeDef HAL_JPEG_GetState(JPEG_HandleTypeDef *hjpeg) |
| { |
| return hjpeg->State; |
| } |
| |
| /** |
| * @brief Return the JPEG error code |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for the specified JPEG. |
| * @retval JPEG Error Code |
| */ |
| uint32_t HAL_JPEG_GetError(JPEG_HandleTypeDef *hjpeg) |
| { |
| return hjpeg->ErrorCode; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |
| |
| /** @addtogroup JPEG_Private_Functions |
| * @{ |
| */ |
| |
| /** |
| * @brief Generates Huffman sizes/Codes Table from Bits/vals Table |
| * @param Bits pointer to bits table |
| * @param Huffsize pointer to sizes table |
| * @param Huffcode pointer to codes table |
| * @param LastK pointer to last Coeff (table dimension) |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef JPEG_Bits_To_SizeCodes(uint8_t *Bits, uint8_t *Huffsize, uint32_t *Huffcode, uint32_t *LastK) |
| { |
| uint32_t i; |
| uint32_t p; |
| uint32_t l; |
| uint32_t code; |
| uint32_t si; |
| |
| /* Figure C.1: Generation of table of Huffman code sizes */ |
| p = 0; |
| for (l = 0; l < 16UL; l++) |
| { |
| i = (uint32_t)Bits[l]; |
| if ((p + i) > 256UL) |
| { |
| /* check for table overflow */ |
| return HAL_ERROR; |
| } |
| while (i != 0UL) |
| { |
| Huffsize[p] = (uint8_t) l + 1U; |
| p++; |
| i--; |
| } |
| } |
| Huffsize[p] = 0; |
| *LastK = p; |
| |
| /* Figure C.2: Generation of table of Huffman codes */ |
| code = 0; |
| si = Huffsize[0]; |
| p = 0; |
| while (Huffsize[p] != 0U) |
| { |
| while (((uint32_t) Huffsize[p]) == si) |
| { |
| Huffcode[p] = code; |
| p++; |
| code++; |
| } |
| /* code must fit in "size" bits (si), no code is allowed to be all ones*/ |
| if(si > 31UL) |
| { |
| return HAL_ERROR; |
| } |
| if (((uint32_t) code) >= (((uint32_t) 1) << si)) |
| { |
| return HAL_ERROR; |
| } |
| code <<= 1; |
| si++; |
| } |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Transform a Bits/Vals AC Huffman table to sizes/Codes huffman Table |
| * that can programmed to the JPEG encoder registers |
| * @param AC_BitsValsTable pointer to AC huffman bits/vals table |
| * @param AC_SizeCodesTable pointer to AC huffman Sizes/Codes table |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef JPEG_ACHuff_BitsVals_To_SizeCodes(JPEG_ACHuffTableTypeDef *AC_BitsValsTable, |
| JPEG_AC_HuffCodeTableTypeDef *AC_SizeCodesTable) |
| { |
| HAL_StatusTypeDef error; |
| uint8_t huffsize[257]; |
| uint32_t huffcode[257]; |
| uint32_t k; |
| uint32_t l, lsb, msb; |
| uint32_t lastK; |
| |
| error = JPEG_Bits_To_SizeCodes(AC_BitsValsTable->Bits, huffsize, huffcode, &lastK); |
| if (error != HAL_OK) |
| { |
| return error; |
| } |
| |
| /* Figure C.3: Ordering procedure for encoding procedure code tables */ |
| k = 0; |
| |
| while (k < lastK) |
| { |
| l = AC_BitsValsTable->HuffVal[k]; |
| if (l == 0UL) |
| { |
| l = 160; /*l = 0x00 EOB code*/ |
| } |
| else if (l == 0xF0UL) /* l = 0xF0 ZRL code*/ |
| { |
| l = 161; |
| } |
| else |
| { |
| msb = (l & 0xF0UL) >> 4; |
| lsb = (l & 0x0FUL); |
| l = (msb * 10UL) + lsb - 1UL; |
| } |
| if (l >= JPEG_AC_HUFF_TABLE_SIZE) |
| { |
| return HAL_ERROR; /* Huffman Table overflow error*/ |
| } |
| else |
| { |
| AC_SizeCodesTable->HuffmanCode[l] = huffcode[k]; |
| AC_SizeCodesTable->CodeLength[l] = huffsize[k] - 1U; |
| k++; |
| } |
| } |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Transform a Bits/Vals DC Huffman table to sizes/Codes huffman Table |
| * that can programmed to the JPEG encoder registers |
| * @param DC_BitsValsTable pointer to DC huffman bits/vals table |
| * @param DC_SizeCodesTable pointer to DC huffman Sizes/Codes table |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef JPEG_DCHuff_BitsVals_To_SizeCodes(JPEG_DCHuffTableTypeDef *DC_BitsValsTable, |
| JPEG_DC_HuffCodeTableTypeDef *DC_SizeCodesTable) |
| { |
| HAL_StatusTypeDef error; |
| |
| uint32_t k; |
| uint32_t l; |
| uint32_t lastK; |
| uint8_t huffsize[257]; |
| uint32_t huffcode[257]; |
| error = JPEG_Bits_To_SizeCodes(DC_BitsValsTable->Bits, huffsize, huffcode, &lastK); |
| if (error != HAL_OK) |
| { |
| return error; |
| } |
| /* Figure C.3: ordering procedure for encoding procedure code tables */ |
| k = 0; |
| |
| while (k < lastK) |
| { |
| l = DC_BitsValsTable->HuffVal[k]; |
| if (l >= JPEG_DC_HUFF_TABLE_SIZE) |
| { |
| return HAL_ERROR; /* Huffman Table overflow error*/ |
| } |
| else |
| { |
| DC_SizeCodesTable->HuffmanCode[l] = huffcode[k]; |
| DC_SizeCodesTable->CodeLength[l] = huffsize[k] - 1U; |
| k++; |
| } |
| } |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Set the JPEG register with an DC huffman table at the given DC table address |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param HuffTableDC pointer to DC huffman table |
| * @param DCTableAddress Encoder DC huffman table address it could be HUFFENC_DC0 or HUFFENC_DC1. |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef JPEG_Set_HuffDC_Mem(JPEG_HandleTypeDef *hjpeg, JPEG_DCHuffTableTypeDef *HuffTableDC, |
| const __IO uint32_t *DCTableAddress) |
| { |
| HAL_StatusTypeDef error; |
| JPEG_DC_HuffCodeTableTypeDef dcSizeCodesTable; |
| uint32_t i; |
| uint32_t lsb; |
| uint32_t msb; |
| __IO uint32_t *address, *addressDef; |
| |
| if (DCTableAddress == (hjpeg->Instance->HUFFENC_DC0)) |
| { |
| address = (hjpeg->Instance->HUFFENC_DC0 + (JPEG_DC_HUFF_TABLE_SIZE / 2UL)); |
| } |
| else if (DCTableAddress == (hjpeg->Instance->HUFFENC_DC1)) |
| { |
| address = (hjpeg->Instance->HUFFENC_DC1 + (JPEG_DC_HUFF_TABLE_SIZE / 2UL)); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| if (HuffTableDC != NULL) |
| { |
| error = JPEG_DCHuff_BitsVals_To_SizeCodes(HuffTableDC, &dcSizeCodesTable); |
| if (error != HAL_OK) |
| { |
| return error; |
| } |
| addressDef = address; |
| *addressDef = 0x0FFF0FFF; |
| addressDef++; |
| *addressDef = 0x0FFF0FFF; |
| |
| i = JPEG_DC_HUFF_TABLE_SIZE; |
| while (i > 1UL) |
| { |
| i--; |
| address --; |
| msb = ((uint32_t)(((uint32_t)dcSizeCodesTable.CodeLength[i] & 0xFU) << 8)) | ((uint32_t)dcSizeCodesTable.HuffmanCode[i] & |
| 0xFFUL); |
| i--; |
| lsb = ((uint32_t)(((uint32_t)dcSizeCodesTable.CodeLength[i] & 0xFU) << 8)) | ((uint32_t)dcSizeCodesTable.HuffmanCode[i] & |
| 0xFFUL); |
| |
| *address = lsb | (msb << 16); |
| } |
| } |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Set the JPEG register with an AC huffman table at the given AC table address |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param HuffTableAC pointer to AC huffman table |
| * @param ACTableAddress Encoder AC huffman table address it could be HUFFENC_AC0 or HUFFENC_AC1. |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef JPEG_Set_HuffAC_Mem(JPEG_HandleTypeDef *hjpeg, JPEG_ACHuffTableTypeDef *HuffTableAC, |
| const __IO uint32_t *ACTableAddress) |
| { |
| HAL_StatusTypeDef error; |
| JPEG_AC_HuffCodeTableTypeDef acSizeCodesTable; |
| uint32_t i, lsb, msb; |
| __IO uint32_t *address, *addressDef; |
| |
| if (ACTableAddress == (hjpeg->Instance->HUFFENC_AC0)) |
| { |
| address = (hjpeg->Instance->HUFFENC_AC0 + (JPEG_AC_HUFF_TABLE_SIZE / 2UL)); |
| } |
| else if (ACTableAddress == (hjpeg->Instance->HUFFENC_AC1)) |
| { |
| address = (hjpeg->Instance->HUFFENC_AC1 + (JPEG_AC_HUFF_TABLE_SIZE / 2UL)); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| if (HuffTableAC != NULL) |
| { |
| error = JPEG_ACHuff_BitsVals_To_SizeCodes(HuffTableAC, &acSizeCodesTable); |
| if (error != HAL_OK) |
| { |
| return error; |
| } |
| /* Default values settings: 162:167 FFFh , 168:175 FD0h_FD7h */ |
| /* Locations 162:175 of each AC table contain information used internally by the core */ |
| |
| addressDef = address; |
| for (i = 0; i < 3UL; i++) |
| { |
| *addressDef = 0x0FFF0FFF; |
| addressDef++; |
| } |
| *addressDef = 0x0FD10FD0; |
| addressDef++; |
| *addressDef = 0x0FD30FD2; |
| addressDef++; |
| *addressDef = 0x0FD50FD4; |
| addressDef++; |
| *addressDef = 0x0FD70FD6; |
| /* end of Locations 162:175 */ |
| |
| |
| i = JPEG_AC_HUFF_TABLE_SIZE; |
| while (i > 1UL) |
| { |
| i--; |
| address--; |
| msb = ((uint32_t)(((uint32_t)acSizeCodesTable.CodeLength[i] & 0xFU) << 8)) | ((uint32_t)acSizeCodesTable.HuffmanCode[i] & |
| 0xFFUL); |
| i--; |
| lsb = ((uint32_t)(((uint32_t)acSizeCodesTable.CodeLength[i] & 0xFU) << 8)) | ((uint32_t)acSizeCodesTable.HuffmanCode[i] & |
| 0xFFUL); |
| |
| *address = lsb | (msb << 16); |
| } |
| } |
| |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Configure the JPEG encoder register huffman tables to used during |
| * the encdoing operation |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| static HAL_StatusTypeDef JPEG_Set_HuffEnc_Mem(JPEG_HandleTypeDef *hjpeg) |
| { |
| HAL_StatusTypeDef error; |
| |
| JPEG_Set_Huff_DHTMem(hjpeg); |
| error = JPEG_Set_HuffAC_Mem(hjpeg, (JPEG_ACHuffTableTypeDef *)(uint32_t)&JPEG_ACLUM_HuffTable, |
| (hjpeg->Instance->HUFFENC_AC0)); |
| if (error != HAL_OK) |
| { |
| return error; |
| } |
| |
| error = JPEG_Set_HuffAC_Mem(hjpeg, (JPEG_ACHuffTableTypeDef *)(uint32_t)&JPEG_ACCHROM_HuffTable, |
| (hjpeg->Instance->HUFFENC_AC1)); |
| if (error != HAL_OK) |
| { |
| return error; |
| } |
| |
| error = JPEG_Set_HuffDC_Mem(hjpeg, (JPEG_DCHuffTableTypeDef *)(uint32_t)&JPEG_DCLUM_HuffTable, |
| hjpeg->Instance->HUFFENC_DC0); |
| if (error != HAL_OK) |
| { |
| return error; |
| } |
| |
| error = JPEG_Set_HuffDC_Mem(hjpeg, (JPEG_DCHuffTableTypeDef *)(uint32_t)&JPEG_DCCHROM_HuffTable, |
| hjpeg->Instance->HUFFENC_DC1); |
| if (error != HAL_OK) |
| { |
| return error; |
| } |
| /* Return function status */ |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Configure the JPEG register huffman tables to be included in the JPEG |
| * file header (used for encoding only) |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| static void JPEG_Set_Huff_DHTMem(JPEG_HandleTypeDef *hjpeg) |
| { |
| JPEG_ACHuffTableTypeDef *HuffTableAC0 = (JPEG_ACHuffTableTypeDef *)(uint32_t)&JPEG_ACLUM_HuffTable; |
| JPEG_ACHuffTableTypeDef *HuffTableAC1 = (JPEG_ACHuffTableTypeDef *)(uint32_t)&JPEG_ACCHROM_HuffTable; |
| JPEG_DCHuffTableTypeDef *HuffTableDC0 = (JPEG_DCHuffTableTypeDef *)(uint32_t)&JPEG_DCLUM_HuffTable; |
| JPEG_DCHuffTableTypeDef *HuffTableDC1 = (JPEG_DCHuffTableTypeDef *)(uint32_t)&JPEG_DCCHROM_HuffTable; |
| uint32_t value, index; |
| __IO uint32_t *address; |
| |
| /* DC0 Huffman Table : BITS*/ |
| /* DC0 BITS is a 16 Bytes table i.e 4x32bits words from DHTMEM base address to DHTMEM + 3*/ |
| address = (hjpeg->Instance->DHTMEM + 3); |
| index = 16; |
| while (index > 3UL) |
| { |
| |
| *address = (((uint32_t)HuffTableDC0->Bits[index - 1UL] & 0xFFUL) << 24) | |
| (((uint32_t)HuffTableDC0->Bits[index - 2UL] & 0xFFUL) << 16) | |
| (((uint32_t)HuffTableDC0->Bits[index - 3UL] & 0xFFUL) << 8) | |
| ((uint32_t)HuffTableDC0->Bits[index - 4UL] & 0xFFUL); |
| address--; |
| index -= 4UL; |
| |
| } |
| /* DC0 Huffman Table : Val*/ |
| /* DC0 VALS is a 12 Bytes table i.e 3x32bits words from DHTMEM base address +4 to DHTMEM + 6 */ |
| address = (hjpeg->Instance->DHTMEM + 6); |
| index = 12; |
| while (index > 3UL) |
| { |
| *address = (((uint32_t)HuffTableDC0->HuffVal[index - 1UL] & 0xFFUL) << 24) | |
| (((uint32_t)HuffTableDC0->HuffVal[index - 2UL] & 0xFFUL) << 16) | |
| (((uint32_t)HuffTableDC0->HuffVal[index - 3UL] & 0xFFUL) << 8) | |
| ((uint32_t)HuffTableDC0->HuffVal[index - 4UL] & 0xFFUL); |
| address--; |
| index -= 4UL; |
| } |
| |
| /* AC0 Huffman Table : BITS*/ |
| /* AC0 BITS is a 16 Bytes table i.e 4x32bits words from DHTMEM base address + 7 to DHTMEM + 10*/ |
| address = (hjpeg->Instance->DHTMEM + 10UL); |
| index = 16; |
| while (index > 3UL) |
| { |
| |
| *address = (((uint32_t)HuffTableAC0->Bits[index - 1UL] & 0xFFUL) << 24) | |
| (((uint32_t)HuffTableAC0->Bits[index - 2UL] & 0xFFUL) << 16) | |
| (((uint32_t)HuffTableAC0->Bits[index - 3UL] & 0xFFUL) << 8) | |
| ((uint32_t)HuffTableAC0->Bits[index - 4UL] & 0xFFUL); |
| address--; |
| index -= 4UL; |
| |
| } |
| /* AC0 Huffman Table : Val*/ |
| /* AC0 VALS is a 162 Bytes table i.e 41x32bits words from DHTMEM base address + 11 to DHTMEM + 51 */ |
| /* only Byte 0 and Byte 1 of the last word (@ DHTMEM + 51) belong to AC0 VALS table */ |
| address = (hjpeg->Instance->DHTMEM + 51); |
| value = *address & 0xFFFF0000U; |
| value = value | (((uint32_t)HuffTableAC0->HuffVal[161] & 0xFFUL) << 8) | ((uint32_t)HuffTableAC0->HuffVal[160] & 0xFFUL); |
| *address = value; |
| |
| /*continue setting 160 AC0 huffman values */ |
| address--; /* address = hjpeg->Instance->DHTMEM + 50*/ |
| index = 160; |
| while (index > 3UL) |
| { |
| *address = (((uint32_t)HuffTableAC0->HuffVal[index - 1UL] & 0xFFUL) << 24) | |
| (((uint32_t)HuffTableAC0->HuffVal[index - 2UL] & 0xFFUL) << 16) | |
| (((uint32_t)HuffTableAC0->HuffVal[index - 3UL] & 0xFFUL) << 8) | |
| ((uint32_t)HuffTableAC0->HuffVal[index - 4UL] & 0xFFUL); |
| address--; |
| index -= 4UL; |
| } |
| |
| /* DC1 Huffman Table : BITS*/ |
| /* DC1 BITS is a 16 Bytes table i.e 4x32bits words from DHTMEM + 51 base address to DHTMEM + 55*/ |
| /* only Byte 2 and Byte 3 of the first word (@ DHTMEM + 51) belong to DC1 Bits table */ |
| address = (hjpeg->Instance->DHTMEM + 51); |
| value = *address & 0x0000FFFFU; |
| value = value | (((uint32_t)HuffTableDC1->Bits[1] & 0xFFUL) << 24) | (((uint32_t)HuffTableDC1->Bits[0] & 0xFFUL) << 16); |
| *address = value; |
| |
| /* only Byte 0 and Byte 1 of the last word (@ DHTMEM + 55) belong to DC1 Bits table */ |
| address = (hjpeg->Instance->DHTMEM + 55); |
| value = *address & 0xFFFF0000U; |
| value = value | (((uint32_t)HuffTableDC1->Bits[15] & 0xFFUL) << 8) | ((uint32_t)HuffTableDC1->Bits[14] & 0xFFUL); |
| *address = value; |
| |
| /*continue setting 12 DC1 huffman Bits from DHTMEM + 54 down to DHTMEM + 52*/ |
| address--; |
| index = 12; |
| while (index > 3UL) |
| { |
| |
| *address = (((uint32_t)HuffTableDC1->Bits[index + 1UL] & 0xFFUL) << 24) | |
| (((uint32_t)HuffTableDC1->Bits[index] & 0xFFUL) << 16) | |
| (((uint32_t)HuffTableDC1->Bits[index - 1UL] & 0xFFUL) << 8) | |
| ((uint32_t)HuffTableDC1->Bits[index - 2UL] & 0xFFUL); |
| address--; |
| index -= 4UL; |
| |
| } |
| /* DC1 Huffman Table : Val*/ |
| /* DC1 VALS is a 12 Bytes table i.e 3x32bits words from DHTMEM base address +55 to DHTMEM + 58 */ |
| /* only Byte 2 and Byte 3 of the first word (@ DHTMEM + 55) belong to DC1 Val table */ |
| address = (hjpeg->Instance->DHTMEM + 55); |
| value = *address & 0x0000FFFFUL; |
| value = value | (((uint32_t)HuffTableDC1->HuffVal[1] & 0xFFUL) << 24) | (((uint32_t)HuffTableDC1->HuffVal[0] & 0xFFUL) << |
| 16); |
| *address = value; |
| |
| /* only Byte 0 and Byte 1 of the last word (@ DHTMEM + 58) belong to DC1 Val table */ |
| address = (hjpeg->Instance->DHTMEM + 58); |
| value = *address & 0xFFFF0000UL; |
| value = value | (((uint32_t)HuffTableDC1->HuffVal[11] & 0xFFUL) << 8) | ((uint32_t)HuffTableDC1->HuffVal[10] & 0xFFUL); |
| *address = value; |
| |
| /*continue setting 8 DC1 huffman val from DHTMEM + 57 down to DHTMEM + 56*/ |
| address--; |
| index = 8; |
| while (index > 3UL) |
| { |
| *address = (((uint32_t)HuffTableDC1->HuffVal[index + 1UL] & 0xFFUL) << 24) | |
| (((uint32_t)HuffTableDC1->HuffVal[index] & 0xFFUL) << 16) | |
| (((uint32_t)HuffTableDC1->HuffVal[index - 1UL] & 0xFFUL) << 8) | |
| ((uint32_t)HuffTableDC1->HuffVal[index - 2UL] & 0xFFUL); |
| address--; |
| index -= 4UL; |
| } |
| |
| /* AC1 Huffman Table : BITS*/ |
| /* AC1 BITS is a 16 Bytes table i.e 4x32bits words from DHTMEM base address + 58 to DHTMEM + 62*/ |
| /* only Byte 2 and Byte 3 of the first word (@ DHTMEM + 58) belong to AC1 Bits table */ |
| address = (hjpeg->Instance->DHTMEM + 58); |
| value = *address & 0x0000FFFFU; |
| value = value | (((uint32_t)HuffTableAC1->Bits[1] & 0xFFUL) << 24) | (((uint32_t)HuffTableAC1->Bits[0] & 0xFFUL) << 16); |
| *address = value; |
| |
| /* only Byte 0 and Byte 1 of the last word (@ DHTMEM + 62) belong to Bits Val table */ |
| address = (hjpeg->Instance->DHTMEM + 62); |
| value = *address & 0xFFFF0000U; |
| value = value | (((uint32_t)HuffTableAC1->Bits[15] & 0xFFUL) << 8) | ((uint32_t)HuffTableAC1->Bits[14] & 0xFFUL); |
| *address = value; |
| |
| /*continue setting 12 AC1 huffman Bits from DHTMEM + 61 down to DHTMEM + 59*/ |
| address--; |
| index = 12; |
| while (index > 3UL) |
| { |
| |
| *address = (((uint32_t)HuffTableAC1->Bits[index + 1UL] & 0xFFUL) << 24) | |
| (((uint32_t)HuffTableAC1->Bits[index] & 0xFFUL) << 16) | |
| (((uint32_t)HuffTableAC1->Bits[index - 1UL] & 0xFFUL) << 8) | |
| ((uint32_t)HuffTableAC1->Bits[index - 2UL] & 0xFFUL); |
| address--; |
| index -= 4UL; |
| |
| } |
| /* AC1 Huffman Table : Val*/ |
| /* AC1 VALS is a 162 Bytes table i.e 41x32bits words from DHTMEM base address + 62 to DHTMEM + 102 */ |
| /* only Byte 2 and Byte 3 of the first word (@ DHTMEM + 62) belong to AC1 VALS table */ |
| address = (hjpeg->Instance->DHTMEM + 62); |
| value = *address & 0x0000FFFFUL; |
| value = value | (((uint32_t)HuffTableAC1->HuffVal[1] & 0xFFUL) << 24) | (((uint32_t)HuffTableAC1->HuffVal[0] & 0xFFUL) << |
| 16); |
| *address = value; |
| |
| /*continue setting 160 AC1 huffman values from DHTMEM + 63 to DHTMEM+102 */ |
| address = (hjpeg->Instance->DHTMEM + 102); |
| index = 160; |
| while (index > 3UL) |
| { |
| *address = (((uint32_t)HuffTableAC1->HuffVal[index + 1UL] & 0xFFUL) << 24) | |
| (((uint32_t)HuffTableAC1->HuffVal[index] & 0xFFUL) << 16) | |
| (((uint32_t)HuffTableAC1->HuffVal[index - 1UL] & 0xFFUL) << 8) | |
| ((uint32_t)HuffTableAC1->HuffVal[index - 2UL] & 0xFFUL); |
| address--; |
| index -= 4UL; |
| } |
| |
| } |
| |
| /** |
| * @brief Configure the JPEG registers with a given quantization table |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param QTable pointer to an array of 64 bytes giving the quantization table |
| * @param QTableAddress destination quantization address in the JPEG peripheral |
| * it could be QMEM0, QMEM1, QMEM2 or QMEM3 |
| * @retval 0 if no error, 1 if error |
| */ |
| static uint32_t JPEG_Set_Quantization_Mem(JPEG_HandleTypeDef *hjpeg, uint8_t *QTable, |
| __IO uint32_t *QTableAddress) |
| { |
| uint32_t i; |
| uint32_t j; |
| uint32_t quantRow; |
| uint32_t quantVal; |
| uint32_t ScaleFactor; |
| __IO uint32_t *tableAddress; |
| |
| tableAddress = QTableAddress; |
| |
| if ((hjpeg->Conf.ImageQuality >= 50UL) && (hjpeg->Conf.ImageQuality <= 100UL)) |
| { |
| ScaleFactor = 200UL - (hjpeg->Conf.ImageQuality * 2UL); |
| } |
| else if (hjpeg->Conf.ImageQuality > 0UL) |
| { |
| ScaleFactor = ((uint32_t) 5000) / ((uint32_t) hjpeg->Conf.ImageQuality); |
| } |
| else |
| { |
| return 1UL; |
| } |
| |
| /*Quantization_table = (Standard_quanization_table * ScaleFactor + 50) / 100*/ |
| i = 0; |
| while (i < (JPEG_QUANT_TABLE_SIZE - 3UL)) |
| { |
| quantRow = 0; |
| for (j = 0; j < 4UL; j++) |
| { |
| /* Note that the quantization coefficients must be specified in the table in zigzag order */ |
| quantVal = ((((uint32_t) QTable[JPEG_ZIGZAG_ORDER[i + j]]) * ScaleFactor) + 50UL) / 100UL; |
| |
| if (quantVal == 0UL) |
| { |
| quantVal = 1UL; |
| } |
| else if (quantVal > 255UL) |
| { |
| quantVal = 255UL; |
| } |
| else |
| { |
| /* Nothing to do, keep same value of quantVal */ |
| } |
| |
| quantRow |= ((quantVal & 0xFFUL) << (8UL * j)); |
| } |
| |
| i += 4UL; |
| *tableAddress = quantRow; |
| tableAddress ++; |
| } |
| |
| /* Return function status */ |
| return 0UL; |
| } |
| |
| /** |
| * @brief Configure the JPEG registers for YCbCr color space |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| static void JPEG_SetColorYCBCR(JPEG_HandleTypeDef *hjpeg) |
| { |
| uint32_t ySamplingH; |
| uint32_t ySamplingV; |
| uint32_t yblockNb; |
| |
| /*Set Number of color components to 3*/ |
| hjpeg->Instance->CONFR1 &= ~JPEG_CONFR1_NF; |
| hjpeg->Instance->CONFR1 |= JPEG_CONFR1_NF_1; |
| |
| /* compute MCU block size and Y, Cb ,Cr sampling factors*/ |
| if (hjpeg->Conf.ChromaSubsampling == JPEG_420_SUBSAMPLING) |
| { |
| ySamplingH = JPEG_CONFR4_HSF_1; /* Hs = 2*/ |
| ySamplingV = JPEG_CONFR4_VSF_1; /* Vs = 2*/ |
| |
| yblockNb = 0x30; /* 4 blocks of 8x8*/ |
| } |
| else if (hjpeg->Conf.ChromaSubsampling == JPEG_422_SUBSAMPLING) |
| { |
| ySamplingH = JPEG_CONFR4_HSF_1; /* Hs = 2*/ |
| ySamplingV = JPEG_CONFR4_VSF_0; /* Vs = 1*/ |
| |
| yblockNb = 0x10; /* 2 blocks of 8x8*/ |
| } |
| else /*JPEG_444_SUBSAMPLING and default*/ |
| { |
| ySamplingH = JPEG_CONFR4_HSF_0; /* Hs = 1*/ |
| ySamplingV = JPEG_CONFR4_VSF_0; /* Vs = 1*/ |
| |
| yblockNb = 0; /* 1 block of 8x8*/ |
| } |
| |
| hjpeg->Instance->CONFR1 &= ~(JPEG_CONFR1_NF | JPEG_CONFR1_NS); |
| hjpeg->Instance->CONFR1 |= (JPEG_CONFR1_NF_1 | JPEG_CONFR1_NS_1); |
| |
| /*Reset CONFR4 register*/ |
| hjpeg->Instance->CONFR4 = 0; |
| /*Set Horizental and Vertical sampling factor , number of blocks , Quantization table and Huffman AC/DC tables for component 0*/ |
| hjpeg->Instance->CONFR4 |= (ySamplingH | ySamplingV | (yblockNb & JPEG_CONFR4_NB)); |
| |
| /*Reset CONFR5 register*/ |
| hjpeg->Instance->CONFR5 = 0; |
| /*Set Horizental and Vertical sampling factor , number of blocks , Quantization table and Huffman AC/DC tables for component 1*/ |
| hjpeg->Instance->CONFR5 |= (JPEG_CONFR5_HSF_0 | JPEG_CONFR5_VSF_0 | JPEG_CONFR5_QT_0 | JPEG_CONFR5_HA | JPEG_CONFR5_HD); |
| |
| /*Reset CONFR6 register*/ |
| hjpeg->Instance->CONFR6 = 0; |
| /*Set Horizental and Vertical sampling factor and number of blocks for component 2*/ |
| /* In YCBCR , by default, both chrominance components (component 1 and component 2) use the same Quantization table (table 1) */ |
| /* In YCBCR , both chrominance components (component 1 and component 2) use the same Huffman tables (table 1) */ |
| hjpeg->Instance->CONFR6 |= (JPEG_CONFR6_HSF_0 | JPEG_CONFR6_VSF_0 | JPEG_CONFR6_QT_0 | JPEG_CONFR6_HA | JPEG_CONFR6_HD); |
| |
| } |
| |
| /** |
| * @brief Configure the JPEG registers for GrayScale color space |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| static void JPEG_SetColorGrayScale(JPEG_HandleTypeDef *hjpeg) |
| { |
| /*Set Number of color components to 1*/ |
| hjpeg->Instance->CONFR1 &= ~(JPEG_CONFR1_NF | JPEG_CONFR1_NS); |
| |
| /*in GrayScale use 1 single Quantization table (Table 0)*/ |
| /*in GrayScale use only one couple of AC/DC huffman table (table 0)*/ |
| |
| /*Reset CONFR4 register*/ |
| hjpeg->Instance->CONFR4 = 0; |
| /*Set Horizental and Vertical sampling factor , number of blocks , Quantization table and Huffman AC/DC tables for component 0*/ |
| hjpeg->Instance->CONFR4 |= JPEG_CONFR4_HSF_0 | JPEG_CONFR4_VSF_0 ; |
| } |
| |
| /** |
| * @brief Configure the JPEG registers for CMYK color space |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| static void JPEG_SetColorCMYK(JPEG_HandleTypeDef *hjpeg) |
| { |
| uint32_t ySamplingH; |
| uint32_t ySamplingV; |
| uint32_t yblockNb; |
| |
| /*Set Number of color components to 4*/ |
| hjpeg->Instance->CONFR1 |= (JPEG_CONFR1_NF | JPEG_CONFR1_NS); |
| |
| /* compute MCU block size and Y, Cb ,Cr sampling factors*/ |
| if (hjpeg->Conf.ChromaSubsampling == JPEG_420_SUBSAMPLING) |
| { |
| ySamplingH = JPEG_CONFR4_HSF_1; /* Hs = 2*/ |
| ySamplingV = JPEG_CONFR4_VSF_1; /* Vs = 2*/ |
| |
| yblockNb = 0x30; /* 4 blocks of 8x8*/ |
| } |
| else if (hjpeg->Conf.ChromaSubsampling == JPEG_422_SUBSAMPLING) |
| { |
| ySamplingH = JPEG_CONFR4_HSF_1; /* Hs = 2*/ |
| ySamplingV = JPEG_CONFR4_VSF_0; /* Vs = 1*/ |
| |
| yblockNb = 0x10; /* 2 blocks of 8x8*/ |
| } |
| else /*JPEG_444_SUBSAMPLING and default*/ |
| { |
| ySamplingH = JPEG_CONFR4_HSF_0; /* Hs = 1*/ |
| ySamplingV = JPEG_CONFR4_VSF_0; /* Vs = 1*/ |
| |
| yblockNb = 0; /* 1 block of 8x8*/ |
| } |
| |
| /*Reset CONFR4 register*/ |
| hjpeg->Instance->CONFR4 = 0; |
| /*Set Horizental and Vertical sampling factor , number of blocks , Quantization table and Huffman AC/DC tables for component 0*/ |
| hjpeg->Instance->CONFR4 |= (ySamplingH | ySamplingV | (yblockNb & JPEG_CONFR4_NB)); |
| |
| /*Reset CONFR5 register*/ |
| hjpeg->Instance->CONFR5 = 0; |
| /*Set Horizental and Vertical sampling factor , number of blocks , Quantization table and Huffman AC/DC tables for component 1*/ |
| hjpeg->Instance->CONFR5 |= (JPEG_CONFR5_HSF_0 | JPEG_CONFR5_VSF_0); |
| |
| /*Reset CONFR6 register*/ |
| hjpeg->Instance->CONFR6 = 0; |
| /*Set Horizental and Vertical sampling factor , number of blocks , Quantization table and Huffman AC/DC tables for component 2*/ |
| hjpeg->Instance->CONFR6 |= (JPEG_CONFR6_HSF_0 | JPEG_CONFR6_VSF_0); |
| |
| /*Reset CONFR7 register*/ |
| hjpeg->Instance->CONFR7 = 0; |
| /*Set Horizental and Vertical sampling factor , number of blocks , Quantization table and Huffman AC/DC tables for component 3*/ |
| hjpeg->Instance->CONFR7 |= (JPEG_CONFR7_HSF_0 | JPEG_CONFR7_VSF_0); |
| } |
| |
| /** |
| * @brief Init the JPEG encoding/decoding process in case of Polling or Interrupt and DMA |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None |
| */ |
| static void JPEG_Init_Process(JPEG_HandleTypeDef *hjpeg) |
| { |
| /*Reset pause*/ |
| hjpeg->Context &= (~(JPEG_CONTEXT_PAUSE_INPUT | JPEG_CONTEXT_PAUSE_OUTPUT)); |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) |
| { |
| /*Set JPEG Codec to Decoding mode */ |
| hjpeg->Instance->CONFR1 |= JPEG_CONFR1_DE; |
| } |
| else /* JPEG_CONTEXT_ENCODE */ |
| { |
| /*Set JPEG Codec to Encoding mode */ |
| hjpeg->Instance->CONFR1 &= ~JPEG_CONFR1_DE; |
| } |
| |
| /*Stop JPEG processing */ |
| hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; |
| |
| /* Disable All Interrupts */ |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); |
| |
| /* Flush input and output FIFOs*/ |
| hjpeg->Instance->CR |= JPEG_CR_IFF; |
| hjpeg->Instance->CR |= JPEG_CR_OFF; |
| |
| /* Clear all flags */ |
| __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); |
| |
| /*Start Encoding/Decoding*/ |
| hjpeg->Instance->CONFR0 |= JPEG_CONFR0_START; |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) |
| { |
| /*Enable IN/OUT, end of Conversation, and end of header parsing interruptions*/ |
| __HAL_JPEG_ENABLE_IT(hjpeg, JPEG_IT_IFT | JPEG_IT_IFNF | JPEG_IT_OFT | JPEG_IT_OFNE | JPEG_IT_EOC | JPEG_IT_HPD); |
| } |
| else if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) |
| { |
| /*Enable End Of Conversation, and End Of Header parsing interruptions*/ |
| __HAL_JPEG_ENABLE_IT(hjpeg, JPEG_IT_EOC | JPEG_IT_HPD); |
| |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| } |
| |
| /** |
| * @brief JPEG encoding/decoding process in case of Polling or Interrupt |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval JPEG_PROCESS_DONE if the process has ends else JPEG_PROCESS_ONGOING |
| */ |
| static uint32_t JPEG_Process(JPEG_HandleTypeDef *hjpeg) |
| { |
| uint32_t tmpContext; |
| |
| /*End of header processing flag */ |
| if ((hjpeg->Context & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) |
| { |
| if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_HPDF) != 0UL) |
| { |
| /*Call Header parsing complete callback */ |
| (void) HAL_JPEG_GetInfo(hjpeg, &hjpeg->Conf); |
| /* Reset the ImageQuality */ |
| hjpeg->Conf.ImageQuality = 0; |
| /* Note : the image quality is only available at the end of the decoding operation */ |
| /* at the current stage the calculated image quality is not correct so reset it */ |
| |
| /*Call Info Ready callback */ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->InfoReadyCallback(hjpeg, &hjpeg->Conf); |
| #else |
| HAL_JPEG_InfoReadyCallback(hjpeg, &hjpeg->Conf); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_IT_HPD); |
| |
| /* Clear header processing done flag */ |
| __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_HPDF); |
| } |
| } |
| |
| /*Input FIFO status handling*/ |
| if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_INPUT) == 0UL) |
| { |
| if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_IFTF) != 0UL) |
| { |
| /*Input FIFO threshold flag */ |
| /*JPEG_FIFO_TH_SIZE words can be written in */ |
| JPEG_ReadInputData(hjpeg, JPEG_FIFO_TH_SIZE); |
| } |
| else if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_IFNFF) != 0UL) |
| { |
| /*Input FIFO Not Full flag */ |
| /*32-bit value can be written in */ |
| JPEG_ReadInputData(hjpeg, 1); |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| } |
| |
| |
| /*Output FIFO flag handling*/ |
| if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL) |
| { |
| if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFTF) != 0UL) |
| { |
| /*Output FIFO threshold flag */ |
| /*JPEG_FIFO_TH_SIZE words can be read out */ |
| JPEG_StoreOutputData(hjpeg, JPEG_FIFO_TH_SIZE); |
| } |
| else if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) != 0UL) |
| { |
| /*Output FIFO Not Empty flag */ |
| /*32-bit value can be read out */ |
| JPEG_StoreOutputData(hjpeg, 1); |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| } |
| |
| /*End of Conversion handling :i.e EOC flag is high and OFTF low and OFNEF low*/ |
| if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_EOCF | JPEG_FLAG_OFTF | JPEG_FLAG_OFNEF) == JPEG_FLAG_EOCF) |
| { |
| /*Stop Encoding/Decoding*/ |
| hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) |
| { |
| /* Disable All Interrupts */ |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); |
| } |
| |
| /* Clear all flags */ |
| __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); |
| |
| /*Call End of conversion callback */ |
| if (hjpeg->JpegOutCount > 0UL) |
| { |
| /*Output Buffer is not empty, call DecodedDataReadyCallback*/ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #else |
| HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| hjpeg->JpegOutCount = 0; |
| } |
| |
| /*Reset Context Operation*/ |
| tmpContext = hjpeg->Context; |
| /*Clear all context fields execpt JPEG_CONTEXT_CONF_ENCODING and JPEG_CONTEXT_CUSTOM_TABLES*/ |
| hjpeg->Context &= (JPEG_CONTEXT_CONF_ENCODING | JPEG_CONTEXT_CUSTOM_TABLES); |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| /*Call End of Encoding/Decoding callback */ |
| if ((tmpContext & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) |
| { |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DecodeCpltCallback(hjpeg); |
| #else |
| HAL_JPEG_DecodeCpltCallback(hjpeg); |
| #endif /*USE_HAL_JPEG_REGISTER_CALLBACKS*/ |
| } |
| else /* JPEG_CONTEXT_ENCODE */ |
| { |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->EncodeCpltCallback(hjpeg); |
| #else |
| HAL_JPEG_EncodeCpltCallback(hjpeg); |
| #endif |
| } |
| |
| return JPEG_PROCESS_DONE; |
| } |
| |
| |
| return JPEG_PROCESS_ONGOING; |
| } |
| |
| /** |
| * @brief Store some output data from the JPEG peripheral to the output buffer. |
| * This function is used when the JPEG peripheral has new data to output |
| * in case of Polling or Interrupt process |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param nbOutputWords Number of output words (of 32 bits) ready from the JPEG peripheral |
| * @retval None |
| */ |
| static void JPEG_StoreOutputData(JPEG_HandleTypeDef *hjpeg, uint32_t nbOutputWords) |
| { |
| uint32_t index; |
| uint32_t nb_words; |
| uint32_t nb_bytes; |
| uint32_t dataword; |
| |
| if (hjpeg->OutDataLength >= (hjpeg->JpegOutCount + (nbOutputWords * 4UL))) |
| { |
| for (index = 0; index < nbOutputWords; index++) |
| { |
| /*Transfer 32 bits from the JPEG output FIFO*/ |
| dataword = hjpeg->Instance->DOR; |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)(dataword & 0x000000FFUL); |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 1UL] = (uint8_t)((dataword & 0x0000FF00UL) >> 8); |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 2UL] = (uint8_t)((dataword & 0x00FF0000UL) >> 16); |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 3UL] = (uint8_t)((dataword & 0xFF000000UL) >> 24); |
| hjpeg->JpegOutCount += 4UL; |
| } |
| if (hjpeg->OutDataLength == hjpeg->JpegOutCount) |
| { |
| /*Output Buffer is full, call DecodedDataReadyCallback*/ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #else |
| HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #endif /*USE_HAL_JPEG_REGISTER_CALLBACKS*/ |
| hjpeg->JpegOutCount = 0; |
| } |
| } |
| else if (hjpeg->OutDataLength > hjpeg->JpegOutCount) |
| { |
| nb_words = (hjpeg->OutDataLength - hjpeg->JpegOutCount) / 4UL; |
| for (index = 0; index < nb_words; index++) |
| { |
| /*Transfer 32 bits from the JPEG output FIFO*/ |
| dataword = hjpeg->Instance->DOR; |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)(dataword & 0x000000FFUL); |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 1UL] = (uint8_t)((dataword & 0x0000FF00UL) >> 8); |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 2UL] = (uint8_t)((dataword & 0x00FF0000UL) >> 16); |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 3UL] = (uint8_t)((dataword & 0xFF000000UL) >> 24); |
| hjpeg->JpegOutCount += 4UL; |
| } |
| if (hjpeg->OutDataLength == hjpeg->JpegOutCount) |
| { |
| /*Output Buffer is full, call DecodedDataReadyCallback*/ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #else |
| HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| hjpeg->JpegOutCount = 0; |
| } |
| else |
| { |
| nb_bytes = hjpeg->OutDataLength - hjpeg->JpegOutCount; |
| dataword = hjpeg->Instance->DOR; |
| for (index = 0; index < nb_bytes; index++) |
| { |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)((dataword >> (8UL * (index & 0x3UL))) & 0xFFUL); |
| hjpeg->JpegOutCount++; |
| } |
| /*Output Buffer is full, call DecodedDataReadyCallback*/ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #else |
| HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| hjpeg->JpegOutCount = 0; |
| |
| nb_bytes = 4UL - nb_bytes; |
| for (index = nb_bytes; index < 4UL; index++) |
| { |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)((dataword >> (8UL * index)) & 0xFFUL); |
| hjpeg->JpegOutCount++; |
| } |
| } |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| } |
| |
| /** |
| * @brief Read some input Data from the input buffer. |
| * This function is used when the JPEG peripheral needs new data |
| * in case of Polling or Interrupt process |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @param nbRequestWords Number of input words (of 32 bits) that the JPE peripheral request |
| * @retval None |
| */ |
| static void JPEG_ReadInputData(JPEG_HandleTypeDef *hjpeg, uint32_t nbRequestWords) |
| { |
| uint32_t nb_bytes = 0; |
| uint32_t nb_words; |
| uint32_t index; |
| uint32_t dataword; |
| uint32_t input_count; |
| |
| if ((hjpeg->InDataLength == 0UL) || (nbRequestWords == 0UL)) |
| { |
| /* No more Input data : nothing to do*/ |
| (void) HAL_JPEG_Pause(hjpeg, JPEG_PAUSE_RESUME_INPUT); |
| } |
| else if (hjpeg->InDataLength > hjpeg->JpegInCount) |
| { |
| nb_bytes = hjpeg->InDataLength - hjpeg->JpegInCount; |
| } |
| else if (hjpeg->InDataLength == hjpeg->JpegInCount) |
| { |
| /*Call HAL_JPEG_GetDataCallback to get new data */ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->GetDataCallback(hjpeg, hjpeg->JpegInCount); |
| #else |
| HAL_JPEG_GetDataCallback(hjpeg, hjpeg->JpegInCount); |
| #endif /*USE_HAL_JPEG_REGISTER_CALLBACKS*/ |
| |
| if (hjpeg->InDataLength > 4UL) |
| { |
| hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % 4UL); |
| } |
| hjpeg->JpegInCount = 0; |
| nb_bytes = hjpeg->InDataLength; |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| if (((hjpeg->Context & JPEG_CONTEXT_PAUSE_INPUT) == 0UL) && (nb_bytes > 0UL)) |
| { |
| nb_words = nb_bytes / 4UL; |
| if (nb_words >= nbRequestWords) |
| { |
| for (index = 0; index < nbRequestWords; index++) |
| { |
| input_count = hjpeg->JpegInCount; |
| hjpeg->Instance->DIR = (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count])) | \ |
| (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 1UL])) << 8) | \ |
| (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 2UL])) << 16) | \ |
| (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 3UL])) << 24)); |
| |
| hjpeg->JpegInCount += 4UL; |
| } |
| } |
| else /*nb_words < nbRequestWords*/ |
| { |
| if (nb_words > 0UL) |
| { |
| for (index = 0; index < nb_words; index++) |
| { |
| input_count = hjpeg->JpegInCount; |
| hjpeg->Instance->DIR = (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count])) | \ |
| (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 1UL])) << 8) | \ |
| (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 2UL])) << 16) | \ |
| (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 3UL])) << 24)); |
| |
| hjpeg->JpegInCount += 4UL; |
| } |
| } |
| else |
| { |
| /* end of file*/ |
| dataword = 0; |
| for (index = 0; index < nb_bytes; index++) |
| { |
| dataword |= (uint32_t)hjpeg->pJpegInBuffPtr[hjpeg->JpegInCount] << (8UL * (index & 0x03UL)); |
| hjpeg->JpegInCount++; |
| } |
| hjpeg->Instance->DIR = dataword; |
| } |
| } |
| } |
| } |
| |
| /** |
| * @brief Start the JPEG DMA process (encoding/decoding) |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval JPEG_PROCESS_DONE if process ends else JPEG_PROCESS_ONGOING |
| */ |
| static HAL_StatusTypeDef JPEG_DMA_StartProcess(JPEG_HandleTypeDef *hjpeg) |
| { |
| uint32_t inXfrSize, outXfrSize; |
| |
| /*if the MDMA In is triggred with JPEG In FIFO Threshold flag |
| then MDMA In buffer size is 32 bytes |
| else (MDMA In is triggred with JPEG In FIFO not full flag) |
| then MDMA In buffer size is 4 bytes |
| */ |
| inXfrSize = hjpeg->hdmain->Init.BufferTransferLength; |
| |
| /*if the MDMA Out is triggred with JPEG Out FIFO Threshold flag |
| then MDMA out buffer size is 32 bytes |
| else (MDMA Out is triggred with JPEG Out FIFO not empty flag) |
| then MDMA buffer size is 4 bytes |
| */ |
| outXfrSize = hjpeg->hdmaout->Init.BufferTransferLength; |
| |
| if ((hjpeg->InDataLength < inXfrSize) || (hjpeg->OutDataLength < outXfrSize)) |
| { |
| return HAL_ERROR; |
| } |
| /* Set the JPEG MDMA In transfer complete callback */ |
| hjpeg->hdmain->XferCpltCallback = JPEG_MDMAInCpltCallback; |
| /* Set the MDMA In error callback */ |
| hjpeg->hdmain->XferErrorCallback = JPEG_MDMAErrorCallback; |
| |
| /* Set the JPEG MDMA Out transfer complete callback */ |
| hjpeg->hdmaout->XferCpltCallback = JPEG_MDMAOutCpltCallback; |
| /* Set the MDMA In error callback */ |
| hjpeg->hdmaout->XferErrorCallback = JPEG_MDMAErrorCallback; |
| /* Set the MDMA Out Abort callback */ |
| hjpeg->hdmaout->XferAbortCallback = JPEG_MDMAOutAbortCallback; |
| |
| if ((inXfrSize == 0UL) || (outXfrSize == 0UL)) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| return HAL_ERROR; |
| } |
| /*MDMA transfer size (BNDTR) must be a multiple of MDMA buffer size (TLEN)*/ |
| hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % inXfrSize); |
| |
| /*MDMA transfer size (BNDTR) must be a multiple of MDMA buffer size (TLEN)*/ |
| hjpeg->OutDataLength = hjpeg->OutDataLength - (hjpeg->OutDataLength % outXfrSize); |
| |
| |
| /* Start MDMA FIFO Out transfer */ |
| if (HAL_MDMA_Start_IT(hjpeg->hdmaout, (uint32_t)&hjpeg->Instance->DOR, (uint32_t)hjpeg->pJpegOutBuffPtr, |
| hjpeg->OutDataLength, 1) != HAL_OK) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| return HAL_ERROR; |
| } |
| /* Start DMA FIFO In transfer */ |
| if (HAL_MDMA_Start_IT(hjpeg->hdmain, (uint32_t)hjpeg->pJpegInBuffPtr, (uint32_t)&hjpeg->Instance->DIR, |
| hjpeg->InDataLength, 1) != HAL_OK) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Continue the current JPEG DMA process (encoding/decoding) |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval JPEG_PROCESS_DONE if process ends else JPEG_PROCESS_ONGOING |
| */ |
| static void JPEG_DMA_ContinueProcess(JPEG_HandleTypeDef *hjpeg) |
| { |
| /*End of header processing flag rises*/ |
| if ((hjpeg->Context & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) |
| { |
| if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_HPDF) != 0UL) |
| { |
| /*Call Header parsing complete callback */ |
| (void) HAL_JPEG_GetInfo(hjpeg, &hjpeg->Conf); |
| |
| /* Reset the ImageQuality */ |
| hjpeg->Conf.ImageQuality = 0; |
| /* Note : the image quality is only available at the end of the decoding operation */ |
| /* at the current stage the calculated image quality is not correct so reset it */ |
| |
| /*Call Info Ready callback */ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->InfoReadyCallback(hjpeg, &hjpeg->Conf); |
| #else |
| HAL_JPEG_InfoReadyCallback(hjpeg, &hjpeg->Conf); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_IT_HPD); |
| |
| /* Clear header processing done flag */ |
| __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_HPDF); |
| } |
| } |
| |
| /*End of Conversion handling*/ |
| if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_EOCF) != 0UL) |
| { |
| |
| hjpeg->Context |= JPEG_CONTEXT_ENDING_DMA; |
| |
| /*Stop Encoding/Decoding*/ |
| hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; |
| |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); |
| |
| /* Clear all flags */ |
| __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); |
| |
| if (hjpeg->hdmain->State == HAL_MDMA_STATE_BUSY) |
| { |
| /* Stop the MDMA In Xfer*/ |
| (void) HAL_MDMA_Abort_IT(hjpeg->hdmain); |
| } |
| |
| if (hjpeg->hdmaout->State == HAL_MDMA_STATE_BUSY) |
| { |
| /* Stop the MDMA out Xfer*/ |
| (void) HAL_MDMA_Abort_IT(hjpeg->hdmaout); |
| } |
| else |
| { |
| JPEG_DMA_EndProcess(hjpeg); |
| } |
| } |
| |
| |
| } |
| |
| /** |
| * @brief Finalize the current JPEG DMA process (encoding/decoding) |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval JPEG_PROCESS_DONE |
| */ |
| static void JPEG_DMA_EndProcess(JPEG_HandleTypeDef *hjpeg) |
| { |
| uint32_t tmpContext; |
| hjpeg->JpegOutCount = hjpeg->OutDataLength - (hjpeg->hdmaout->Instance->CBNDTR & MDMA_CBNDTR_BNDT); |
| |
| /*if Output Buffer is full, call HAL_JPEG_DataReadyCallback*/ |
| if (hjpeg->JpegOutCount == hjpeg->OutDataLength) |
| { |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #else |
| HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| hjpeg->JpegOutCount = 0; |
| } |
| |
| /*Check if remaining data in the output FIFO*/ |
| if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) == 0UL) |
| { |
| if (hjpeg->JpegOutCount > 0UL) |
| { |
| /*Output Buffer is not empty, call DecodedDataReadyCallback*/ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #else |
| HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| hjpeg->JpegOutCount = 0; |
| } |
| |
| /*Stop Encoding/Decoding*/ |
| hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; |
| |
| tmpContext = hjpeg->Context; |
| /*Clear all context fields execpt JPEG_CONTEXT_CONF_ENCODING and JPEG_CONTEXT_CUSTOM_TABLES*/ |
| hjpeg->Context &= (JPEG_CONTEXT_CONF_ENCODING | JPEG_CONTEXT_CUSTOM_TABLES); |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| /*Call End of Encoding/Decoding callback */ |
| if ((tmpContext & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) |
| { |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DecodeCpltCallback(hjpeg); |
| #else |
| HAL_JPEG_DecodeCpltCallback(hjpeg); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| } |
| else /* JPEG_CONTEXT_ENCODE */ |
| { |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->EncodeCpltCallback(hjpeg); |
| #else |
| HAL_JPEG_EncodeCpltCallback(hjpeg); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| } |
| } |
| else if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL) |
| { |
| JPEG_DMA_PollResidualData(hjpeg); |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| |
| } |
| |
| /** |
| * @brief Poll residual output data when DMA process (encoding/decoding) |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval None. |
| */ |
| static void JPEG_DMA_PollResidualData(JPEG_HandleTypeDef *hjpeg) |
| { |
| uint32_t tmpContext; |
| uint32_t count; |
| uint32_t dataOut; |
| |
| for (count = JPEG_FIFO_SIZE; count > 0UL; count--) |
| { |
| if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL) |
| { |
| if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) != 0UL) |
| { |
| dataOut = hjpeg->Instance->DOR; |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)(dataOut & 0x000000FFUL); |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 1UL] = (uint8_t)((dataOut & 0x0000FF00UL) >> 8); |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 2UL] = (uint8_t)((dataOut & 0x00FF0000UL) >> 16); |
| hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 3UL] = (uint8_t)((dataOut & 0xFF000000UL) >> 24); |
| hjpeg->JpegOutCount += 4UL; |
| |
| if (hjpeg->JpegOutCount == hjpeg->OutDataLength) |
| { |
| /*Output Buffer is full, call HAL_JPEG_DataReadyCallback*/ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #else |
| HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| hjpeg->JpegOutCount = 0; |
| } |
| |
| } |
| } |
| } |
| |
| tmpContext = hjpeg->Context; |
| |
| if ((__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) == 0UL) || ((tmpContext & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL)) |
| { |
| /*Stop Encoding/Decoding*/ |
| hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; |
| |
| if (hjpeg->JpegOutCount > 0UL) |
| { |
| /*Output Buffer is not empty, call DecodedDataReadyCallback*/ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #else |
| HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| hjpeg->JpegOutCount = 0; |
| } |
| |
| tmpContext = hjpeg->Context; |
| /*Clear all context fields execpt JPEG_CONTEXT_CONF_ENCODING and JPEG_CONTEXT_CUSTOM_TABLES*/ |
| hjpeg->Context &= (JPEG_CONTEXT_CONF_ENCODING | JPEG_CONTEXT_CUSTOM_TABLES); |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hjpeg); |
| |
| /* Change the JPEG state */ |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| |
| /*Call End of Encoding/Decoding callback */ |
| if ((tmpContext & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) |
| { |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DecodeCpltCallback(hjpeg); |
| #else |
| HAL_JPEG_DecodeCpltCallback(hjpeg); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| } |
| else /* JPEG_CONTEXT_ENCODE */ |
| { |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->EncodeCpltCallback(hjpeg); |
| #else |
| HAL_JPEG_EncodeCpltCallback(hjpeg); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| } |
| } |
| } |
| |
| /** |
| * @brief MDMA input transfer complete callback |
| * @param hmdma pointer to a MDMA_HandleTypeDef structure. |
| * @retval None |
| */ |
| static void JPEG_MDMAInCpltCallback(MDMA_HandleTypeDef *hmdma) |
| { |
| uint32_t inXfrSize; |
| |
| JPEG_HandleTypeDef *hjpeg = (JPEG_HandleTypeDef *)((MDMA_HandleTypeDef *)hmdma)->Parent; |
| |
| /* Disable The JPEG IT so the MDMA Input Callback can not be interrupted by the JPEG EOC IT or JPEG HPD IT */ |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); |
| |
| /* Check if context method is DMA and we are not in ending DMA stage */ |
| if ((hjpeg->Context & (JPEG_CONTEXT_METHOD_MASK | JPEG_CONTEXT_ENDING_DMA)) == JPEG_CONTEXT_DMA) |
| { |
| |
| /*if the MDMA In is triggred with JPEG In FIFO Threshold flag |
| then MDMA In buffer size is 32 bytes |
| else (MDMA In is triggred with JPEG In FIFO not full flag) |
| then MDMA In buffer size is 4 bytes |
| */ |
| inXfrSize = hjpeg->hdmain->Init.BufferTransferLength; |
| |
| hjpeg->JpegInCount = hjpeg->InDataLength - (hmdma->Instance->CBNDTR & MDMA_CBNDTR_BNDT); |
| |
| /*Call HAL_JPEG_GetDataCallback to get new data */ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->GetDataCallback(hjpeg, hjpeg->JpegInCount); |
| #else |
| HAL_JPEG_GetDataCallback(hjpeg, hjpeg->JpegInCount); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| |
| if (hjpeg->InDataLength >= inXfrSize) |
| { |
| if (inXfrSize == 0UL) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->ErrorCallback(hjpeg); |
| #else |
| HAL_JPEG_ErrorCallback(hjpeg); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| return; |
| } |
| /*JPEG Input MDMA transfer data number must be multiple of MDMA buffer size |
| as the destination is a 32 bits register */ |
| hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % inXfrSize); |
| |
| } |
| else if (hjpeg->InDataLength > 0UL) |
| { |
| /* Transfer the remaining Data, must be multiple of source data size (byte) and destination data size (word) */ |
| if ((hjpeg->InDataLength % 4UL) != 0UL) |
| { |
| hjpeg->InDataLength = ((hjpeg->InDataLength / 4UL) + 1UL) * 4UL; |
| } |
| } |
| else |
| { |
| /* Nothing to do */ |
| } |
| |
| if (((hjpeg->Context & JPEG_CONTEXT_PAUSE_INPUT) == 0UL) && (hjpeg->InDataLength > 0UL)) |
| { |
| /* Start MDMA FIFO In transfer */ |
| if (HAL_MDMA_Start_IT(hjpeg->hdmain, (uint32_t)hjpeg->pJpegInBuffPtr, (uint32_t)&hjpeg->Instance->DIR, |
| hjpeg->InDataLength, 1) != HAL_OK) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->ErrorCallback(hjpeg); |
| #else |
| HAL_JPEG_ErrorCallback(hjpeg); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| return; |
| } |
| } |
| |
| /* JPEG Conversion still on going : Enable the JPEG IT */ |
| __HAL_JPEG_ENABLE_IT(hjpeg, JPEG_IT_EOC | JPEG_IT_HPD); |
| } |
| } |
| |
| /** |
| * @brief MDMA output transfer complete callback |
| * @param hmdma pointer to a MDMA_HandleTypeDef structure. |
| * @retval None |
| */ |
| static void JPEG_MDMAOutCpltCallback(MDMA_HandleTypeDef *hmdma) |
| { |
| JPEG_HandleTypeDef *hjpeg = (JPEG_HandleTypeDef *)((MDMA_HandleTypeDef *)hmdma)->Parent; |
| |
| |
| /* Disable The JPEG IT so the MDMA Output Callback can not be interrupted by the JPEG EOC IT or JPEG HPD IT */ |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); |
| |
| if ((hjpeg->Context & (JPEG_CONTEXT_METHOD_MASK | JPEG_CONTEXT_ENDING_DMA)) == |
| JPEG_CONTEXT_DMA) /* Check if context method is DMA and we are not in ending DMA stage */ |
| { |
| if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_EOCF) == 0UL) |
| { |
| hjpeg->JpegOutCount = hjpeg->OutDataLength - (hmdma->Instance->CBNDTR & MDMA_CBNDTR_BNDT); |
| |
| /*Output Buffer is full, call HAL_JPEG_DataReadyCallback*/ |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #else |
| HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL) |
| { |
| /* Start MDMA FIFO Out transfer */ |
| if (HAL_MDMA_Start_IT(hjpeg->hdmaout, (uint32_t)&hjpeg->Instance->DOR, (uint32_t)hjpeg->pJpegOutBuffPtr, |
| hjpeg->OutDataLength, 1) != HAL_OK) |
| { |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| hjpeg->State = HAL_JPEG_STATE_ERROR; |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->ErrorCallback(hjpeg); |
| #else |
| HAL_JPEG_ErrorCallback(hjpeg); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| return; |
| } |
| } |
| } |
| |
| /* JPEG Conversion still on going : Enable the JPEG IT */ |
| __HAL_JPEG_ENABLE_IT(hjpeg, JPEG_IT_EOC | JPEG_IT_HPD); |
| } |
| |
| } |
| |
| /** |
| * @brief MDMA Transfer error callback |
| * @param hmdma pointer to a MDMA_HandleTypeDef structure. |
| * @retval None |
| */ |
| static void JPEG_MDMAErrorCallback(MDMA_HandleTypeDef *hmdma) |
| { |
| JPEG_HandleTypeDef *hjpeg = (JPEG_HandleTypeDef *)((MDMA_HandleTypeDef *)hmdma)->Parent; |
| |
| /*Stop Encoding/Decoding*/ |
| hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; |
| |
| /* Disable All Interrupts */ |
| __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); |
| |
| hjpeg->State = HAL_JPEG_STATE_READY; |
| hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; |
| |
| #if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) |
| hjpeg->ErrorCallback(hjpeg); |
| #else |
| HAL_JPEG_ErrorCallback(hjpeg); |
| #endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ |
| } |
| |
| /** |
| * @brief MDMA output Abort callback |
| * @param hmdma pointer to a MDMA_HandleTypeDef structure. |
| * @retval None |
| */ |
| static void JPEG_MDMAOutAbortCallback(MDMA_HandleTypeDef *hmdma) |
| { |
| JPEG_HandleTypeDef *hjpeg = (JPEG_HandleTypeDef *)((MDMA_HandleTypeDef *)hmdma)->Parent; |
| |
| if ((hjpeg->Context & JPEG_CONTEXT_ENDING_DMA) != 0UL) |
| { |
| JPEG_DMA_EndProcess(hjpeg); |
| } |
| } |
| |
| |
| /** |
| * @brief Calculate the decoded image quality (from 1 to 100) |
| * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains |
| * the configuration information for JPEG module |
| * @retval JPEG image quality from 1 to 100. |
| */ |
| static uint32_t JPEG_GetQuality(JPEG_HandleTypeDef *hjpeg) |
| { |
| uint32_t quality = 0; |
| uint32_t quantRow, quantVal, scale, i, j; |
| __IO uint32_t *tableAddress = hjpeg->Instance->QMEM0; |
| |
| i = 0; |
| while (i < (JPEG_QUANT_TABLE_SIZE - 3UL)) |
| { |
| quantRow = *tableAddress; |
| for (j = 0; j < 4UL; j++) |
| { |
| quantVal = (quantRow >> (8UL * j)) & 0xFFUL; |
| if (quantVal == 1UL) |
| { |
| /* if Quantization value = 1 then quality is 100%*/ |
| quality += 100UL; |
| } |
| else |
| { |
| /* Note that the quantization coefficients must be specified in the table in zigzag order */ |
| scale = (quantVal * 100UL) / ((uint32_t) hjpeg->QuantTable0[JPEG_ZIGZAG_ORDER[i + j]]); |
| |
| if (scale <= 100UL) |
| { |
| quality += (200UL - scale) / 2UL; |
| } |
| else |
| { |
| quality += 5000UL / scale; |
| } |
| } |
| } |
| |
| i += 4UL; |
| tableAddress ++; |
| } |
| |
| return (quality / 64UL); |
| } |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| #endif /* JPEG */ |
| #endif /* HAL_JPEG_MODULE_ENABLED */ |
| |
| |
| /** |
| * @} |
| */ |
| |