/** | |
****************************************************************************** | |
* @file stm32f7xx_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 | |
* | |
@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). | |
@endverbatim | |
****************************************************************************** | |
* @attention | |
* | |
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> | |
* | |
* Redistribution and use in source and binary forms, with or without modification, | |
* are permitted provided that the following conditions are met: | |
* 1. Redistributions of source code must retain the above copyright notice, | |
* this list of conditions and the following disclaimer. | |
* 2. Redistributions in binary form must reproduce the above copyright notice, | |
* this list of conditions and the following disclaimer in the documentation | |
* and/or other materials provided with the distribution. | |
* 3. Neither the name of STMicroelectronics nor the names of its contributors | |
* may be used to endorse or promote products derived from this software | |
* without specific prior written permission. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
* | |
****************************************************************************** | |
*/ | |
/* Includes ------------------------------------------------------------------*/ | |
#include "stm32f7xx_hal.h" | |
/** @addtogroup STM32F7xx_HAL_Driver | |
* @{ | |
*/ | |
/** @defgroup JPEG JPEG | |
* @brief JPEG HAL module driver. | |
* @{ | |
*/ | |
#ifdef HAL_JPEG_MODULE_ENABLED | |
#if defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) | |
/* Private define ------------------------------------------------------------*/ | |
/** @addtogroup JPEG_Private_Constants | |
* @{ | |
*/ | |
#define JPEG_TIMEOUT_VALUE ((uint32_t)1000U) /* 1s */ | |
#define JPEG_AC_HUFF_TABLE_SIZE ((uint32_t)162U) /* Huffman AC table size : 162 codes*/ | |
#define JPEG_DC_HUFF_TABLE_SIZE ((uint32_t)12U) /* Huffman AC table size : 12 codes*/ | |
#define JPEG_FIFO_SIZE ((uint32_t)16U) /* JPEG Input/Output HW FIFO size in words*/ | |
#define JPEG_INTERRUPT_MASK ((uint32_t)0x0000007EU) /* JPEG Interrupt Mask*/ | |
#define JPEG_DMA_MASK ((uint32_t)0x00001800U) /* JPEG DMA request Mask*/ | |
#define JPEG_DMA_IDMA ((uint32_t)JPEG_CR_IDMAEN) /* DMA request for the input FIFO */ | |
#define JPEG_DMA_ODMA ((uint32_t)JPEG_CR_ODMAEN) /* DMA request for the output FIFO */ | |
#define JPEG_CONTEXT_ENCODE ((uint32_t)0x00000001U) /* JPEG context : operation is encoding*/ | |
#define JPEG_CONTEXT_DECODE ((uint32_t)0x00000002U) /* JPEG context : operation is decoding*/ | |
#define JPEG_CONTEXT_OPERATION_MASK ((uint32_t)0x00000003U) /* JPEG context : operation Mask */ | |
#define JPEG_CONTEXT_POLLING ((uint32_t)0x00000004U) /* JPEG context : Transfer use Polling */ | |
#define JPEG_CONTEXT_IT ((uint32_t)0x00000008U) /* JPEG context : Transfer use Interrupt */ | |
#define JPEG_CONTEXT_DMA ((uint32_t)0x0000000CU) /* JPEG context : Transfer use DMA */ | |
#define JPEG_CONTEXT_METHOD_MASK ((uint32_t)0x0000000CU) /* JPEG context : Transfer Mask */ | |
#define JPEG_CONTEXT_CONF_ENCODING ((uint32_t)0x00000100U) /* JPEG context : encoding config done */ | |
#define JPEG_CONTEXT_PAUSE_INPUT ((uint32_t)0x00001000U) /* JPEG context : Pause Input */ | |
#define JPEG_CONTEXT_PAUSE_OUTPUT ((uint32_t)0x00002000U) /* JPEG context : Pause Output */ | |
#define JPEG_CONTEXT_CUSTOM_TABLES ((uint32_t)0x00004000U) /* JPEG context : Use custom quantization tables */ | |
#define JPEG_CONTEXT_ENDING_DMA ((uint32_t)0x00008000U) /* JPEG context : ending with DMA in progress */ | |
#define JPEG_PROCESS_ONGOING ((uint32_t)0x00000000U) /* Process is on going */ | |
#define JPEG_PROCESS_DONE ((uint32_t)0x00000001U) /* 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 -------------------------------------------------------------*/ | |
/** @addtogroup JPEG_Private_Macros | |
* @{ | |
*/ | |
#define JPEG_ENABLE_DMA(__HANDLE__,__DMA__) ((__HANDLE__)->Instance->CR |= ((__DMA__) & JPEG_DMA_MASK)) | |
/*note : To disable a DMA request we must use MODIFY_REG macro to avoid writing "1" to the FIFO flush bits | |
located in the same DMA request enable register (CR register). */ | |
#define JPEG_DISABLE_DMA(__HANDLE__,__DMA__) MODIFY_REG((__HANDLE__)->Instance->CR, ((__DMA__) & JPEG_DMA_MASK), 0) | |
/** | |
* @} | |
*/ | |
/* 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 } | |
}; | |
/* | |
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 | |
}; | |
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, uint32_t *DCTableAddress); | |
static HAL_StatusTypeDef JPEG_Set_HuffAC_Mem(JPEG_HandleTypeDef *hjpeg, JPEG_ACHuffTableTypeDef *HuffTableAC, uint32_t *ACTableAddress); | |
static HAL_StatusTypeDef JPEG_Set_HuffEnc_Mem(JPEG_HandleTypeDef *hjpeg, JPEG_ACHuffTableTypeDef *HuffTableAC0, JPEG_DCHuffTableTypeDef *HuffTableDC0 , JPEG_ACHuffTableTypeDef *HuffTableAC1, JPEG_DCHuffTableTypeDef *HuffTableDC1); | |
static void JPEG_Set_Huff_DHTMem(JPEG_HandleTypeDef *hjpeg, JPEG_ACHuffTableTypeDef *HuffTableAC0, JPEG_DCHuffTableTypeDef *HuffTableDC0 , JPEG_ACHuffTableTypeDef *HuffTableAC1, JPEG_DCHuffTableTypeDef *HuffTableDC1); | |
static HAL_StatusTypeDef JPEG_Set_Quantization_Mem(JPEG_HandleTypeDef *hjpeg, uint8_t *QTable, 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 uint32_t JPEG_DMA_ContinueProcess(JPEG_HandleTypeDef *hjpeg); | |
static uint32_t JPEG_DMA_EndProcess(JPEG_HandleTypeDef *hjpeg); | |
static void JPEG_DMA_PollResidualData(JPEG_HandleTypeDef *hjpeg); | |
static void JPEG_DMAOutCpltCallback(DMA_HandleTypeDef *hdma); | |
static void JPEG_DMAInCpltCallback(DMA_HandleTypeDef *hdma); | |
static void JPEG_DMAErrorCallback(DMA_HandleTypeDef *hdma); | |
static void JPEG_DMAOutAbortCallback(DMA_HandleTypeDef *hdma) ; | |
/** | |
* @} | |
*/ | |
/** @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) | |
{ | |
/*Note : these intermediate variables are used to avoid MISRA warning | |
regarding rule 11.5 */ | |
uint32_t acLum_huffmanTableAddr = (uint32_t)(&JPEG_ACLUM_HuffTable); | |
uint32_t dcLum_huffmanTableAddr = (uint32_t)(&JPEG_DCLUM_HuffTable); | |
uint32_t acChrom_huffmanTableAddr = (uint32_t)(&JPEG_ACCHROM_HuffTable); | |
uint32_t dcChrom_huffmanTableAddr = (uint32_t)(&JPEG_DCCHROM_HuffTable); | |
/* Check the JPEG handle allocation */ | |
if(hjpeg == NULL) | |
{ | |
return HAL_ERROR; | |
} | |
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); | |
} | |
/* 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); | |
/* Disable All DMA requests */ | |
JPEG_DISABLE_DMA(hjpeg,JPEG_DMA_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); | |
hjpeg->QuantTable0 = (uint8_t *)JPEG_LUM_QuantTable; | |
hjpeg->QuantTable1 = (uint8_t *)JPEG_CHROM_QuantTable; | |
hjpeg->QuantTable2 = NULL; | |
hjpeg->QuantTable3 = NULL; | |
/* init the default Huffman tables*/ | |
if(JPEG_Set_HuffEnc_Mem(hjpeg, (JPEG_ACHuffTableTypeDef *)acLum_huffmanTableAddr, (JPEG_DCHuffTableTypeDef *)dcLum_huffmanTableAddr, (JPEG_ACHuffTableTypeDef *)acChrom_huffmanTableAddr, (JPEG_DCHuffTableTypeDef *)dcChrom_huffmanTableAddr) != 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; | |
} | |
/* DeInit the low level hardware: CLOCK, NVIC.*/ | |
HAL_JPEG_MspDeInit(hjpeg); | |
/* 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 | |
*/ | |
} | |
/** | |
* @} | |
*/ | |
/** @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 = HAL_OK; | |
uint32_t numberMCU, hfactor, vfactor,hMCU, 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, (uint32_t *)(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, (uint32_t *)(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, (uint32_t *)(hjpeg->Instance->QMEM1)); | |
if((hjpeg->Context & JPEG_CONTEXT_CUSTOM_TABLES) != 0) /*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, (uint32_t *)(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 if(hjpeg->Conf.ColorSpace == JPEG_CMYK_COLORSPACE) | |
{ | |
JPEG_SetColorCMYK(hjpeg); | |
/* Set quantization table 0*/ | |
error = JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable0, (uint32_t *)(hjpeg->Instance->QMEM0)); | |
/*By default quantization table 0 for All components*/ | |
if((hjpeg->Context & JPEG_CONTEXT_CUSTOM_TABLES) != 0) /*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, (uint32_t *)(hjpeg->Instance->QMEM1)); | |
error |= JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable2, (uint32_t *)(hjpeg->Instance->QMEM2)); | |
error |= JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable3, (uint32_t *)(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 != HAL_OK) | |
{ | |
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*/ | |
MODIFY_REG(hjpeg->Instance->CONFR1, JPEG_CONFR1_YSIZE, ((hjpeg->Conf.ImageHeight & 0x0000FFFF) << 16)); /* set the number of lines*/ | |
MODIFY_REG(hjpeg->Instance->CONFR3, JPEG_CONFR3_XSIZE, ((hjpeg->Conf.ImageWidth & 0x0000FFFF) << 16)); /* set the number of pixels per line*/ | |
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) != 0) | |
{ | |
hMCU++; /*+1 for horizontal incomplete MCU */ | |
} | |
vMCU = (hjpeg->Conf.ImageHeight / vfactor); | |
if((hjpeg->Conf.ImageHeight % vfactor) != 0) | |
{ | |
vMCU++; /*+1 for vertical incomplete MCU */ | |
} | |
numberMCU = (hMCU * vMCU) - 1; /* 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 informations | |
* @retval HAL status | |
*/ | |
HAL_StatusTypeDef HAL_JPEG_GetInfo(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo) | |
{ | |
uint32_t yblockNb, cBblockNb, 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) == 0) | |
{ | |
pInfo->ColorSpace = JPEG_GRAYSCALE_COLORSPACE; | |
} | |
else if((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == JPEG_CONFR1_NF) | |
{ | |
pInfo->ColorSpace = JPEG_CMYK_COLORSPACE; | |
} | |
pInfo->ImageHeight = (hjpeg->Instance->CONFR1 & 0xFFFF0000U) >> 16; | |
pInfo->ImageWidth = (hjpeg->Instance->CONFR3 & 0xFFFF0000U) >> 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 == 1) && (cBblockNb == 0) && (cRblockNb == 0)) | |
{ | |
pInfo->ChromaSubsampling = JPEG_422_SUBSAMPLING; /*16x8 block*/ | |
} | |
else if((yblockNb == 0) && (cBblockNb == 0) && (cRblockNb == 0)) | |
{ | |
pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; | |
} | |
else if((yblockNb == 3) && (cBblockNb == 0) && (cRblockNb == 0)) | |
{ | |
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 = 0; | |
/* Check the parameters */ | |
assert_param((InDataLength >= 4)); | |
assert_param((OutDataLength >= 4)); | |
/* Check In/out buffer allocation and size */ | |
if((hjpeg == NULL) || (pDataInMCU == NULL) || (pDataOut == NULL) || \ | |
(InDataLength == 0) || (OutDataLength == 0)) | |
{ | |
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(); | |
/*In/Out Data length must be multiple of 4 Bytes (1 word)*/ | |
InDataLength = InDataLength - (InDataLength % 4); | |
OutDataLength = OutDataLength - (OutDataLength % 4); | |
/*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 data processing : In/Out FIFO transfer*/ | |
while((JPEG_Process(hjpeg) == JPEG_PROCESS_ONGOING)) | |
{ | |
if(Timeout != HAL_MAX_DELAY) | |
{ | |
if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) | |
{ | |
/* 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 = 0; | |
/* Check the parameters */ | |
assert_param((InDataLength >= 4)); | |
assert_param((OutDataLength >= 4)); | |
/* Check In/out buffer allocation and size */ | |
if((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL) || \ | |
(InDataLength == 0) || (OutDataLength == 0)) | |
{ | |
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); | |
/*In/Out Data length must be multiple of 4 Bytes (1 word)*/ | |
InDataLength = InDataLength - (InDataLength % 4); | |
OutDataLength = OutDataLength - (OutDataLength % 4); | |
/*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 data processing : In/Out FIFO transfer*/ | |
while((JPEG_Process(hjpeg) == JPEG_PROCESS_ONGOING)) | |
{ | |
if(Timeout != HAL_MAX_DELAY) | |
{ | |
if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) | |
{ | |
/* 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 >= 4)); | |
assert_param((OutDataLength >= 4)); | |
/* Check In/out buffer allocation and size */ | |
if((hjpeg == NULL) || (pDataInMCU == NULL) || (pDataOut == NULL) || \ | |
(InDataLength == 0) || (OutDataLength == 0)) | |
{ | |
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); | |
/*In/Out Data length must be multiple of 4 Bytes (1 word)*/ | |
InDataLength = InDataLength - (InDataLength % 4); | |
OutDataLength = OutDataLength - (OutDataLength % 4); | |
/*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); | |
} | |
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 >= 4)); | |
assert_param((OutDataLength >= 4)); | |
/* Check In/out buffer allocation and size */ | |
if((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL) || \ | |
(InDataLength == 0) || (OutDataLength == 0)) | |
{ | |
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); | |
/*In/Out Data length must be multiple of 4 Bytes (1 word)*/ | |
InDataLength = InDataLength - (InDataLength % 4); | |
OutDataLength = OutDataLength - (OutDataLength % 4); | |
/*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); | |
} | |
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 >= 4)); | |
assert_param((OutDataLength >= 4)); | |
/* Check In/out buffer allocation and size */ | |
if((hjpeg == NULL) || (pDataInMCU == NULL) || (pDataOut == NULL) || \ | |
(InDataLength == 0) || (OutDataLength == 0)) | |
{ | |
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 */ | |
JPEG_DMA_StartProcess(hjpeg); | |
} | |
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 >= 4)); | |
assert_param((OutDataLength >= 4)); | |
/* Check In/out buffer allocation and size */ | |
if((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL) || \ | |
(InDataLength == 0) || (OutDataLength == 0)) | |
{ | |
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 */ | |
JPEG_DMA_StartProcess(hjpeg); | |
} | |
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; | |
mask |= JPEG_DMA_IDMA; | |
} | |
if((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) | |
{ | |
hjpeg->Context |= JPEG_CONTEXT_PAUSE_OUTPUT; | |
mask |= JPEG_DMA_ODMA; | |
} | |
JPEG_DISABLE_DMA(hjpeg,mask); | |
} | |
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); | |
} | |
/* 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; | |
assert_param(IS_JPEG_PAUSE_RESUME_STATE(XferSelection)); | |
if(((hjpeg->Context & JPEG_CONTEXT_PAUSE_INPUT) == 0) && ((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0)) | |
{ | |
/* 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); | |
mask |= JPEG_DMA_IDMA; | |
/*JPEG Input DMA transfer data number must be multiple of DMA buffer size | |
as the destination is a 32 bits register */ | |
hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % 4); | |
if(hjpeg->InDataLength > 0) | |
{ | |
/* Start DMA FIFO In transfer */ | |
HAL_DMA_Start_IT(hjpeg->hdmain, (uint32_t)hjpeg->pJpegInBuffPtr, (uint32_t)&hjpeg->Instance->DIR, hjpeg->InDataLength >> 2); | |
} | |
} | |
if((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) | |
{ | |
if((hjpeg->Context & JPEG_CONTEXT_ENDING_DMA) != 0) | |
{ | |
JPEG_DMA_PollResidualData(hjpeg); | |
} | |
else | |
{ | |
hjpeg->Context &= (~JPEG_CONTEXT_PAUSE_OUTPUT); | |
mask |= JPEG_DMA_ODMA; | |
/* Start DMA FIFO Out transfer */ | |
HAL_DMA_Start_IT(hjpeg->hdmaout, (uint32_t)&hjpeg->Instance->DOR, (uint32_t)hjpeg->pJpegOutBuffPtr, hjpeg->OutDataLength >> 2); | |
} | |
} | |
JPEG_ENABLE_DMA(hjpeg,mask); | |
} | |
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); | |
} | |
/* 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, 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*/ | |
HAL_DMA_Abort(hjpeg->hdmaout); | |
HAL_DMA_Abort(hjpeg->hdmain); | |
} | |
/* 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) != RESET) | |
{ | |
/* 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_TIMEOUT; | |
/* Process Unlocked */ | |
__HAL_UNLOCK(hjpeg); | |
return HAL_TIMEOUT; | |
} | |
} | |
/* Disable All Interrupts */ | |
__HAL_JPEG_DISABLE_IT(hjpeg,JPEG_INTERRUPT_MASK); | |
/* Disable All DMA requests */ | |
JPEG_DISABLE_DMA(hjpeg,JPEG_DMA_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*/ | |
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 informations | |
* @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) | |
{ | |
JPEG_Process(hjpeg); | |
} | |
else if((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) | |
{ | |
JPEG_DMA_ContinueProcess(hjpeg); | |
} | |
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 dimmension) | |
* @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, p, l, code, si; | |
/* Figure C.1: Generation of table of Huffman code sizes */ | |
p = 0; | |
for (l = 0; l < 16; l++) | |
{ | |
i = (uint32_t)Bits[l]; | |
if ( (p + i) > 256) | |
{ /* check for table overflow */ | |
return HAL_ERROR; | |
} | |
while (i != 0) | |
{ | |
Huffsize[p++] = (uint8_t) l+1; | |
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] != 0) | |
{ | |
while (((uint32_t) Huffsize[p]) == si) | |
{ | |
Huffcode[p++] = code; | |
code++; | |
} | |
/* code must fit in "size" bits (si), no code is allowed to be all ones*/ | |
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 == 0) | |
{ | |
l = 160; /*l = 0x00 EOB code*/ | |
} | |
else if(l == 0xF0)/* l = 0xF0 ZRL code*/ | |
{ | |
l = 161; | |
} | |
else | |
{ | |
msb = (l & 0xF0) >> 4; | |
lsb = (l & 0x0F); | |
l = (msb * 10) + lsb - 1; | |
} | |
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] - 1; | |
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] - 1; | |
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, uint32_t *DCTableAddress) | |
{ | |
HAL_StatusTypeDef error = HAL_OK; | |
JPEG_DC_HuffCodeTableTypeDef dcSizeCodesTable; | |
uint32_t i, lsb, msb; | |
__IO uint32_t *address, *addressDef; | |
if(DCTableAddress == (uint32_t *)(hjpeg->Instance->HUFFENC_DC0)) | |
{ | |
address = (hjpeg->Instance->HUFFENC_DC0 + (JPEG_DC_HUFF_TABLE_SIZE/2)); | |
} | |
else if (DCTableAddress == (uint32_t *)(hjpeg->Instance->HUFFENC_DC1)) | |
{ | |
address = (hjpeg->Instance->HUFFENC_DC1 + (JPEG_DC_HUFF_TABLE_SIZE/2)); | |
} | |
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>0) | |
{ | |
i--; | |
address --; | |
msb = ((uint32_t)(((uint32_t)dcSizeCodesTable.CodeLength[i] & 0xF) << 8 )) | ((uint32_t)dcSizeCodesTable.HuffmanCode[i] & 0xFF); | |
i--; | |
lsb = ((uint32_t)(((uint32_t)dcSizeCodesTable.CodeLength[i] & 0xF) << 8 )) | ((uint32_t)dcSizeCodesTable.HuffmanCode[i] & 0xFF); | |
*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, uint32_t *ACTableAddress) | |
{ | |
HAL_StatusTypeDef error = HAL_OK; | |
JPEG_AC_HuffCodeTableTypeDef acSizeCodesTable; | |
uint32_t i, lsb, msb; | |
__IO uint32_t *address, *addressDef; | |
if(ACTableAddress == (uint32_t *)(hjpeg->Instance->HUFFENC_AC0)) | |
{ | |
address = (hjpeg->Instance->HUFFENC_AC0 + (JPEG_AC_HUFF_TABLE_SIZE/2)); | |
} | |
else if (ACTableAddress == (uint32_t *)(hjpeg->Instance->HUFFENC_AC1)) | |
{ | |
address = (hjpeg->Instance->HUFFENC_AC1 + (JPEG_AC_HUFF_TABLE_SIZE/2)); | |
} | |
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<3; 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 > 0) | |
{ | |
i--; | |
address--; | |
msb = ((uint32_t)(((uint32_t)acSizeCodesTable.CodeLength[i] & 0xF) << 8 )) | ((uint32_t)acSizeCodesTable.HuffmanCode[i] & 0xFF); | |
i--; | |
lsb = ((uint32_t)(((uint32_t)acSizeCodesTable.CodeLength[i] & 0xF) << 8 )) | ((uint32_t)acSizeCodesTable.HuffmanCode[i] & 0xFF); | |
*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 | |
* @param HuffTableAC0: AC0 huffman table | |
* @param HuffTableDC0: DC0 huffman table | |
* @param HuffTableAC1: AC1 huffman table | |
* @param HuffTableDC1: DC1 huffman table | |
* @retval None | |
*/ | |
static HAL_StatusTypeDef JPEG_Set_HuffEnc_Mem(JPEG_HandleTypeDef *hjpeg, JPEG_ACHuffTableTypeDef *HuffTableAC0, JPEG_DCHuffTableTypeDef *HuffTableDC0 , JPEG_ACHuffTableTypeDef *HuffTableAC1, JPEG_DCHuffTableTypeDef *HuffTableDC1) | |
{ | |
HAL_StatusTypeDef error = HAL_OK; | |
JPEG_Set_Huff_DHTMem(hjpeg, HuffTableAC0, HuffTableDC0, HuffTableAC1, HuffTableDC1); | |
if(HuffTableAC0 != NULL) | |
{ | |
error = JPEG_Set_HuffAC_Mem(hjpeg, HuffTableAC0, (uint32_t *)(hjpeg->Instance->HUFFENC_AC0)); | |
if(error != HAL_OK) | |
{ | |
return error; | |
} | |
} | |
if(HuffTableAC1 != NULL) | |
{ | |
error = JPEG_Set_HuffAC_Mem(hjpeg, HuffTableAC1, (uint32_t *)(hjpeg->Instance->HUFFENC_AC1)); | |
if(error != HAL_OK) | |
{ | |
return error; | |
} | |
} | |
if(HuffTableDC0 != NULL) | |
{ | |
error = JPEG_Set_HuffDC_Mem(hjpeg, HuffTableDC0, (uint32_t *)hjpeg->Instance->HUFFENC_DC0); | |
if(error != HAL_OK) | |
{ | |
return error; | |
} | |
} | |
if(HuffTableDC1 != NULL) | |
{ | |
error = JPEG_Set_HuffDC_Mem(hjpeg, HuffTableDC1, (uint32_t *)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 | |
* @param HuffTableAC0: AC0 huffman table | |
* @param HuffTableDC0: DC0 huffman table | |
* @param HuffTableAC1: AC1 huffman table | |
* @param HuffTableDC1: DC1 huffman table | |
* @retval None | |
*/ | |
static void JPEG_Set_Huff_DHTMem(JPEG_HandleTypeDef *hjpeg, JPEG_ACHuffTableTypeDef *HuffTableAC0, JPEG_DCHuffTableTypeDef *HuffTableDC0 , JPEG_ACHuffTableTypeDef *HuffTableAC1, JPEG_DCHuffTableTypeDef *HuffTableDC1) | |
{ | |
uint32_t value, index; | |
__IO uint32_t *address; | |
if(HuffTableDC0 != NULL) | |
{ | |
/* 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 > 0) | |
{ | |
*address = (((uint32_t)HuffTableDC0->Bits[index-1] & 0xFF) << 24)| | |
(((uint32_t)HuffTableDC0->Bits[index-2] & 0xFF) << 16)| | |
(((uint32_t)HuffTableDC0->Bits[index-3] & 0xFF) << 8) | | |
((uint32_t)HuffTableDC0->Bits[index-4] & 0xFF); | |
address--; | |
index -=4; | |
} | |
/* 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 > 0) | |
{ | |
*address = (((uint32_t)HuffTableDC0->HuffVal[index-1] & 0xFF) << 24)| | |
(((uint32_t)HuffTableDC0->HuffVal[index-2] & 0xFF) << 16)| | |
(((uint32_t)HuffTableDC0->HuffVal[index-3] & 0xFF) << 8) | | |
((uint32_t)HuffTableDC0->HuffVal[index-4] & 0xFF); | |
address--; | |
index -=4; | |
} | |
} | |
if(HuffTableAC0 != NULL) | |
{ | |
/* 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 + 10); | |
index = 16; | |
while(index > 0) | |
{ | |
*address = (((uint32_t)HuffTableAC0->Bits[index-1] & 0xFF) << 24)| | |
(((uint32_t)HuffTableAC0->Bits[index-2] & 0xFF) << 16)| | |
(((uint32_t)HuffTableAC0->Bits[index-3] & 0xFF) << 8) | | |
((uint32_t)HuffTableAC0->Bits[index-4] & 0xFF); | |
address--; | |
index -=4; | |
} | |
/* 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] & 0xFF) << 8) | ((uint32_t)HuffTableAC0->HuffVal[160] & 0xFF); | |
*address = value; | |
/*continue setting 160 AC0 huffman values */ | |
address--; /* address = hjpeg->Instance->DHTMEM + 50*/ | |
index = 160; | |
while(index > 0) | |
{ | |
*address = (((uint32_t)HuffTableAC0->HuffVal[index-1] & 0xFF) << 24)| | |
(((uint32_t)HuffTableAC0->HuffVal[index-2] & 0xFF) << 16)| | |
(((uint32_t)HuffTableAC0->HuffVal[index-3] & 0xFF) << 8) | | |
((uint32_t)HuffTableAC0->HuffVal[index-4] & 0xFF); | |
address--; | |
index -=4; | |
} | |
} | |
if(HuffTableDC1 != NULL) | |
{ | |
/* 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] & 0xFF) << 24) | (((uint32_t)HuffTableDC1->Bits[0] & 0xFF) << 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] & 0xFF) << 8) | ((uint32_t)HuffTableDC1->Bits[14] & 0xFF); | |
*address = value; | |
/*continue setting 12 DC1 huffman Bits from DHTMEM + 54 down to DHTMEM + 52*/ | |
address--; | |
index = 12; | |
while(index > 0) | |
{ | |
*address = (((uint32_t)HuffTableDC1->Bits[index+1] & 0xFF) << 24)| | |
(((uint32_t)HuffTableDC1->Bits[index] & 0xFF) << 16)| | |
(((uint32_t)HuffTableDC1->Bits[index-1] & 0xFF) << 8) | | |
((uint32_t)HuffTableDC1->Bits[index-2] & 0xFF); | |
address--; | |
index -=4; | |
} | |
/* 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 & 0x0000FFFF; | |
value = value | (((uint32_t)HuffTableDC1->HuffVal[1] & 0xFF) << 24) | (((uint32_t)HuffTableDC1->HuffVal[0] & 0xFF) << 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 & 0xFFFF0000U; | |
value = value | (((uint32_t)HuffTableDC1->HuffVal[11] & 0xFF) << 8) | ((uint32_t)HuffTableDC1->HuffVal[10] & 0xFF); | |
*address = value; | |
/*continue setting 8 DC1 huffman val from DHTMEM + 57 down to DHTMEM + 56*/ | |
address--; | |
index = 8; | |
while(index > 0) | |
{ | |
*address = (((uint32_t)HuffTableDC1->HuffVal[index+1] & 0xFF) << 24)| | |
(((uint32_t)HuffTableDC1->HuffVal[index] & 0xFF) << 16)| | |
(((uint32_t)HuffTableDC1->HuffVal[index-1] & 0xFF) << 8) | | |
((uint32_t)HuffTableDC1->HuffVal[index-2] & 0xFF); | |
address--; | |
index -=4; | |
} | |
} | |
if(HuffTableAC1 != NULL) | |
{ | |
/* 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] & 0xFF) << 24) | (((uint32_t)HuffTableAC1->Bits[0] & 0xFF) << 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] & 0xFF) << 8) | ((uint32_t)HuffTableAC1->Bits[14] & 0xFF); | |
*address = value; | |
/*continue setting 12 AC1 huffman Bits from DHTMEM + 61 down to DHTMEM + 59*/ | |
address--; | |
index = 12; | |
while(index > 0) | |
{ | |
*address = (((uint32_t)HuffTableAC1->Bits[index+1] & 0xFF) << 24)| | |
(((uint32_t)HuffTableAC1->Bits[index] & 0xFF) << 16)| | |
(((uint32_t)HuffTableAC1->Bits[index-1] & 0xFF) << 8) | | |
((uint32_t)HuffTableAC1->Bits[index-2] & 0xFF); | |
address--; | |
index -=4; | |
} | |
/* 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 & 0x0000FFFF; | |
value = value | (((uint32_t)HuffTableAC1->HuffVal[1] & 0xFF) << 24) | (((uint32_t)HuffTableAC1->HuffVal[0] & 0xFF) << 16); | |
*address = value; | |
/*continue setting 160 AC1 huffman values from DHTMEM + 63 to DHTMEM+102 */ | |
address = (hjpeg->Instance->DHTMEM + 102); | |
index = 160; | |
while(index > 0) | |
{ | |
*address = (((uint32_t)HuffTableAC1->HuffVal[index+1] & 0xFF) << 24)| | |
(((uint32_t)HuffTableAC1->HuffVal[index] & 0xFF) << 16)| | |
(((uint32_t)HuffTableAC1->HuffVal[index-1] & 0xFF) << 8) | | |
((uint32_t)HuffTableAC1->HuffVal[index-2] & 0xFF); | |
address--; | |
index -=4; | |
} | |
} | |
} | |
/** | |
* @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 None | |
*/ | |
static HAL_StatusTypeDef JPEG_Set_Quantization_Mem(JPEG_HandleTypeDef *hjpeg, uint8_t *QTable, uint32_t *QTableAddress) | |
{ | |
uint32_t i, j, *tableAddress, quantRow, quantVal, ScaleFactor; | |
if((QTableAddress == ((uint32_t *)(hjpeg->Instance->QMEM0))) || | |
(QTableAddress == ((uint32_t *)(hjpeg->Instance->QMEM1))) || | |
(QTableAddress == ((uint32_t *)(hjpeg->Instance->QMEM2))) || | |
(QTableAddress == ((uint32_t *)(hjpeg->Instance->QMEM3)))) | |
{ | |
tableAddress = QTableAddress; | |
} | |
else | |
{ | |
return HAL_ERROR; | |
} | |
if ((hjpeg->Conf.ImageQuality >= 50) && (hjpeg->Conf.ImageQuality <= 100)) | |
{ | |
ScaleFactor = 200 - (hjpeg->Conf.ImageQuality * 2); | |
} | |
else if (hjpeg->Conf.ImageQuality > 0) | |
{ | |
ScaleFactor = ((uint32_t) 5000) / ((uint32_t) hjpeg->Conf.ImageQuality); | |
} | |
else | |
{ | |
return HAL_ERROR; | |
} | |
/*Quantization_table = (Standard_quanization_table * ScaleFactor + 50) / 100*/ | |
i = 0; | |
while( i < JPEG_QUANT_TABLE_SIZE) | |
{ | |
quantRow = 0; | |
for(j=0; j<4; 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) + 50) / 100; | |
if(quantVal == 0) | |
{ | |
quantVal = 1; | |
} | |
else if (quantVal > 255) | |
{ | |
quantVal = 255; | |
} | |
quantRow |= ((quantVal & 0xFF) << (8 * j)); | |
} | |
i += 4; | |
*tableAddress = quantRow; | |
tableAddress ++; | |
} | |
/* Return function status */ | |
return HAL_OK; | |
} | |
/** | |
* @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 if((hjpeg->Context & JPEG_CONTEXT_OPERATION_MASK) == 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); | |
/* Disable All DMA requests */ | |
JPEG_DISABLE_DMA(hjpeg,JPEG_DMA_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); | |
} | |
} | |
/** | |
* @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 rised*/ | |
if(((hjpeg->Context & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) && (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_HPDF) != RESET)) | |
{ | |
/*Call Header parsing complet callback */ | |
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 */ | |
HAL_JPEG_InfoReadyCallback(hjpeg, &hjpeg->Conf); | |
__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) == 0) | |
{ | |
if(__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_IFTF) != RESET) | |
{ | |
/*Input FIFO threshold flag rised*/ | |
/*4 words (16 bytes) can be written in */ | |
JPEG_ReadInputData(hjpeg,4); | |
} | |
else if(__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_IFNFF) != RESET) | |
{ | |
/*Input FIFO Not Full flag rised*/ | |
/*32-bit value can be written in */ | |
JPEG_ReadInputData(hjpeg,1); | |
} | |
} | |
/*Output FIFO flag handling*/ | |
if((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0) | |
{ | |
if(__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFTF) != RESET) | |
{ | |
/*Output FIFO threshold flag rised*/ | |
/*4 words (16 bytes) can be read out */ | |
JPEG_StoreOutputData(hjpeg, 4); | |
} | |
else if(__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) != RESET) | |
{ | |
/*Output FIFO Not Empty flag rised*/ | |
/*32-bit value can be read out */ | |
JPEG_StoreOutputData(hjpeg, 1); | |
} | |
} | |
/*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 > 0) | |
{ | |
/*Output Buffer is not empty, call DecodedDataReadyCallback*/ | |
HAL_JPEG_DataReadyCallback (hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); | |
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) | |
{ | |
HAL_JPEG_DecodeCpltCallback(hjpeg); | |
} | |
else if((tmpContext & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_ENCODE) | |
{ | |
HAL_JPEG_EncodeCpltCallback(hjpeg); | |
} | |
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, nBwords, nbBytes , dataword, *pOutData; | |
pOutData = (uint32_t *)(((uint32_t *)hjpeg->pJpegOutBuffPtr) + (hjpeg->JpegOutCount/4)); | |
if(hjpeg->OutDataLength >= (hjpeg->JpegOutCount + (nbOutputWords*4))) | |
{ | |
for(index = 0; index < nbOutputWords; index++) | |
{ | |
/*Transfer 32 bits from the JPEG output FIFO*/ | |
*pOutData = hjpeg->Instance->DOR; | |
pOutData++; | |
hjpeg->JpegOutCount += 4; | |
} | |
if(hjpeg->OutDataLength == hjpeg->JpegOutCount) | |
{ | |
/*Output Buffer is full, call DecodedDataReadyCallback*/ | |
HAL_JPEG_DataReadyCallback (hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); | |
hjpeg->JpegOutCount = 0; | |
} | |
} | |
else if(hjpeg->OutDataLength > hjpeg->JpegOutCount) | |
{ | |
nBwords = (hjpeg->OutDataLength - hjpeg->JpegOutCount)/4; | |
for(index = 0; index < nBwords; index++) | |
{ | |
/*Transfer 32 bits from the JPEG output FIFO*/ | |
*pOutData = hjpeg->Instance->DOR; | |
pOutData++; | |
hjpeg->JpegOutCount += 4; | |
} | |
if(hjpeg->OutDataLength == hjpeg->JpegOutCount) | |
{ | |
/*Output Buffer is full, call DecodedDataReadyCallback*/ | |
HAL_JPEG_DataReadyCallback (hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); | |
hjpeg->JpegOutCount = 0; | |
} | |
else | |
{ | |
nbBytes = hjpeg->OutDataLength - hjpeg->JpegOutCount; | |
dataword = hjpeg->Instance->DOR; | |
for(index = 0; index < nbBytes; index++) | |
{ | |
hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (dataword >> (8*index)) & 0xFF; | |
hjpeg->JpegOutCount++; | |
} | |
/*Output Buffer is full, call DecodedDataReadyCallback*/ | |
HAL_JPEG_DataReadyCallback (hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); | |
hjpeg->JpegOutCount = 0; | |
nbBytes = 4 - nbBytes; | |
for(index = nbBytes; index < 4; index++) | |
{ | |
hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (dataword >> (8*index)) & 0xFF; | |
hjpeg->JpegOutCount++; | |
} | |
} | |
} | |
} | |
/** | |
* @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 nbBytes = 0, nBwords, index, Dataword; | |
if((hjpeg->InDataLength == 0) || (nbRequestWords == 0)) | |
{ | |
/* No more Input data : nothing to do*/ | |
HAL_JPEG_Pause(hjpeg, JPEG_PAUSE_RESUME_INPUT); | |
} | |
else if(hjpeg->InDataLength > hjpeg->JpegInCount) | |
{ | |
nbBytes = hjpeg->InDataLength - hjpeg->JpegInCount; | |
} | |
else if(hjpeg->InDataLength == hjpeg->JpegInCount) | |
{ | |
/*Call HAL_JPEG_GetDataCallback to get new data */ | |
HAL_JPEG_GetDataCallback(hjpeg, hjpeg->JpegInCount); | |
if(hjpeg->InDataLength > 4) | |
{ | |
hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % 4); | |
} | |
hjpeg->JpegInCount = 0; | |
nbBytes = hjpeg->InDataLength; | |
} | |
if((nbBytes > 0) && ((hjpeg->Context & JPEG_CONTEXT_PAUSE_INPUT) == 0)) | |
{ | |
nBwords = nbBytes / 4; | |
if(nBwords >= nbRequestWords) | |
{ | |
for(index = 0; index < nbRequestWords; index++) | |
{ | |
hjpeg->Instance->DIR = *((uint32_t *)(((uint32_t *)hjpeg->pJpegInBuffPtr) + (hjpeg->JpegInCount/4))); | |
hjpeg->JpegInCount += 4; | |
} | |
} | |
else /*nBwords < nbRequestWords*/ | |
{ | |
if(nBwords > 0) | |
{ | |
for(index = 0; index < nBwords; index++) | |
{ | |
hjpeg->Instance->DIR = *((uint32_t *)(((uint32_t *)hjpeg->pJpegInBuffPtr) + (hjpeg->JpegInCount/4))); | |
hjpeg->JpegInCount += 4; | |
} | |
} | |
else | |
{ | |
/* end of file*/ | |
Dataword = 0; | |
for(index=0; index< nbBytes; index++) | |
{ | |
Dataword |= (uint32_t)hjpeg->pJpegInBuffPtr[hjpeg->JpegInCount] << (8 * index); | |
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) | |
{ | |
if((hjpeg->InDataLength < 4) || (hjpeg->OutDataLength < 4)) | |
{ | |
return HAL_ERROR; | |
} | |
/* Reset Ending DMA internal context flag*/ | |
hjpeg->Context &= ~JPEG_CONTEXT_ENDING_DMA; | |
/* Disable DMA In/Out Request*/ | |
JPEG_DISABLE_DMA(hjpeg,JPEG_DMA_ODMA | JPEG_DMA_IDMA); | |
/* Set the JPEG DMA In transfer complete callback */ | |
hjpeg->hdmain->XferCpltCallback = JPEG_DMAInCpltCallback; | |
/* Set the DMA In error callback */ | |
hjpeg->hdmain->XferErrorCallback = JPEG_DMAErrorCallback; | |
/* Set the JPEG DMA Out transfer complete callback */ | |
hjpeg->hdmaout->XferCpltCallback = JPEG_DMAOutCpltCallback; | |
/* Set the DMA Out error callback */ | |
hjpeg->hdmaout->XferErrorCallback = JPEG_DMAErrorCallback; | |
/* Set the DMA Out Abort callback */ | |
hjpeg->hdmaout->XferAbortCallback = JPEG_DMAOutAbortCallback; | |
/*DMA transfer size must be a multiple of 4 bytes i.e mutliple of 32bits words*/ | |
hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % 4); | |
/*DMA transfer size must be a multiple of 4 bytes i.e mutliple of 32bits words*/ | |
hjpeg->OutDataLength = hjpeg->OutDataLength - (hjpeg->OutDataLength % 4); | |
/* Start DMA FIFO In transfer */ | |
HAL_DMA_Start_IT(hjpeg->hdmain, (uint32_t)hjpeg->pJpegInBuffPtr, (uint32_t)&hjpeg->Instance->DIR, hjpeg->InDataLength >> 2); | |
/* Start DMA FIFO Out transfer */ | |
HAL_DMA_Start_IT(hjpeg->hdmaout, (uint32_t)&hjpeg->Instance->DOR, (uint32_t)hjpeg->pJpegOutBuffPtr, hjpeg->OutDataLength >> 2); | |
/* Enable JPEG In/Out DMA requests*/ | |
JPEG_ENABLE_DMA(hjpeg,JPEG_DMA_IDMA | JPEG_DMA_ODMA); | |
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 uint32_t JPEG_DMA_ContinueProcess(JPEG_HandleTypeDef *hjpeg) | |
{ | |
/*End of header processing flag rises*/ | |
if(((hjpeg->Context & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) && (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_HPDF) != RESET)) | |
{ | |
/*Call Header parsing complete callback */ | |
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 */ | |
HAL_JPEG_InfoReadyCallback(hjpeg, &hjpeg->Conf); | |
__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) != RESET) | |
{ | |
/*Disabkle JPEG In/Out DMA Requests*/ | |
JPEG_DISABLE_DMA(hjpeg,JPEG_DMA_ODMA | JPEG_DMA_IDMA); | |
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_DMA_STATE_BUSY) | |
{ | |
/* Stop the DMA In Xfer*/ | |
HAL_DMA_Abort_IT(hjpeg->hdmain); | |
} | |
if(hjpeg->hdmaout->State == HAL_DMA_STATE_BUSY) | |
{ | |
/* Stop the DMA out Xfer*/ | |
HAL_DMA_Abort_IT(hjpeg->hdmaout); | |
} | |
else | |
{ | |
return JPEG_DMA_EndProcess(hjpeg); | |
} | |
} | |
return JPEG_PROCESS_ONGOING; | |
} | |
/** | |
* @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 uint32_t JPEG_DMA_EndProcess(JPEG_HandleTypeDef *hjpeg) | |
{ | |
uint32_t tmpContext; | |
hjpeg->JpegOutCount = hjpeg->OutDataLength - ((hjpeg->hdmaout->Instance->NDTR & DMA_SxNDT) << 2); | |
/*if Output Buffer is full, call HAL_JPEG_DataReadyCallback*/ | |
if(hjpeg->JpegOutCount == hjpeg->OutDataLength) | |
{ | |
HAL_JPEG_DataReadyCallback (hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); | |
hjpeg->JpegOutCount = 0; | |
} | |
/*Check if remaining data in the output FIFO*/ | |
if(__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) == 0) | |
{ | |
/*Stop Encoding/Decoding*/ | |
hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; | |
tmpContext = hjpeg->Context; | |
/*Clear all context fileds 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) | |
{ | |
HAL_JPEG_DecodeCpltCallback(hjpeg); | |
} | |
else if((tmpContext & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_ENCODE) | |
{ | |
HAL_JPEG_EncodeCpltCallback(hjpeg); | |
} | |
} | |
else if((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0) | |
{ | |
JPEG_DMA_PollResidualData(hjpeg); | |
return JPEG_PROCESS_DONE; | |
} | |
return JPEG_PROCESS_ONGOING; | |
} | |
/** | |
* @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, count = JPEG_FIFO_SIZE, *pDataOut; | |
pDataOut = (uint32_t *)(hjpeg->pJpegOutBuffPtr + hjpeg->JpegOutCount); | |
while((__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) != 0) && (count > 0)) | |
{ | |
count--; | |
*pDataOut = hjpeg->Instance->DOR; | |
pDataOut++; | |
hjpeg->JpegOutCount += 4; | |
if(hjpeg->JpegOutCount == hjpeg->OutDataLength) | |
{ | |
/*Output Buffer is full, call HAL_JPEG_DataReadyCallback*/ | |
HAL_JPEG_DataReadyCallback (hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); | |
hjpeg->JpegOutCount = 0; | |
} | |
} | |
/*Stop Encoding/Decoding*/ | |
hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; | |
if(hjpeg->JpegOutCount > 0) | |
{ | |
/*Output Buffer is not empty, call DecodedDataReadyCallback*/ | |
HAL_JPEG_DataReadyCallback (hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); | |
hjpeg->JpegOutCount = 0; | |
} | |
tmpContext = hjpeg->Context; | |
/*Clear all context fileds 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) | |
{ | |
HAL_JPEG_DecodeCpltCallback(hjpeg); | |
} | |
else if((tmpContext & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_ENCODE) | |
{ | |
HAL_JPEG_EncodeCpltCallback(hjpeg); | |
} | |
} | |
/** | |
* @brief DMA input transfer complete callback | |
* @param hdma: pointer to a DMA_HandleTypeDef structure. | |
* @retval None | |
*/ | |
static void JPEG_DMAInCpltCallback(DMA_HandleTypeDef *hdma) | |
{ | |
JPEG_HandleTypeDef* hjpeg = (JPEG_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; | |
/* Disable The JPEG IT so the DMA Input 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_DMA) && ((hjpeg->Context & JPEG_CONTEXT_ENDING_DMA) == 0)) | |
{ | |
JPEG_DISABLE_DMA(hjpeg,JPEG_DMA_IDMA); | |
hjpeg->JpegInCount = hjpeg->InDataLength - ((hdma->Instance->NDTR & DMA_SxNDT) << 2); | |
/*Call HAL_JPEG_GetDataCallback to get new data */ | |
HAL_JPEG_GetDataCallback(hjpeg, hjpeg->JpegInCount); | |
if(hjpeg->InDataLength >= 4) | |
{ | |
/*JPEG Input DMA transfer data number must be multiple of 32 bits word | |
as the destination is a 32 bits (4 bytes) register */ | |
hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % 4); | |
} | |
else if(hjpeg->InDataLength > 0) | |
{ | |
/*Transfer last data word (i.e last 4 bytes)*/ | |
hjpeg->InDataLength = 4; | |
} | |
if(((hjpeg->Context & JPEG_CONTEXT_PAUSE_INPUT) == 0) && (hjpeg->InDataLength > 0)) | |
{ | |
/* Start DMA FIFO In transfer */ | |
HAL_DMA_Start_IT(hjpeg->hdmain, (uint32_t)hjpeg->pJpegInBuffPtr, (uint32_t)&hjpeg->Instance->DIR, hjpeg->InDataLength >> 2); | |
JPEG_ENABLE_DMA(hjpeg,JPEG_DMA_IDMA); | |
} | |
/* JPEG Conversion still on going : Enable the JPEG IT */ | |
__HAL_JPEG_ENABLE_IT(hjpeg,JPEG_IT_EOC |JPEG_IT_HPD); | |
} | |
} | |
/** | |
* @brief DMA output transfer complete callback | |
* @param hdma: pointer to a DMA_HandleTypeDef structure. | |
* @retval None | |
*/ | |
static void JPEG_DMAOutCpltCallback(DMA_HandleTypeDef *hdma) | |
{ | |
JPEG_HandleTypeDef* hjpeg = (JPEG_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; | |
/* Disable The JPEG IT so the DMA 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_DMA) && ((hjpeg->Context & JPEG_CONTEXT_ENDING_DMA) == 0)) | |
{ | |
if(__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_EOCF) == 0) | |
{ | |
JPEG_DISABLE_DMA(hjpeg,JPEG_DMA_ODMA); | |
hjpeg->JpegOutCount = hjpeg->OutDataLength - ((hdma->Instance->NDTR & DMA_SxNDT) << 2); | |
/*Output Buffer is full, call HAL_JPEG_DataReadyCallback*/ | |
HAL_JPEG_DataReadyCallback (hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); | |
if((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0) | |
{ | |
/* Start DMA FIFO Out transfer */ | |
HAL_DMA_Start_IT(hjpeg->hdmaout, (uint32_t)&hjpeg->Instance->DOR, (uint32_t)hjpeg->pJpegOutBuffPtr, hjpeg->OutDataLength >> 2); | |
JPEG_ENABLE_DMA(hjpeg,JPEG_DMA_ODMA); | |
} | |
} | |
/* JPEG Conversion still on going : Enable the JPEG IT */ | |
__HAL_JPEG_ENABLE_IT(hjpeg,JPEG_IT_EOC |JPEG_IT_HPD); | |
} | |
} | |
/** | |
* @brief DMA Transfer error callback | |
* @param hdma: pointer to a DMA_HandleTypeDef structure. | |
* @retval None | |
*/ | |
static void JPEG_DMAErrorCallback(DMA_HandleTypeDef *hdma) | |
{ | |
JPEG_HandleTypeDef* hjpeg = (JPEG_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; | |
/* if DMA error is FIFO error ignore it */ | |
if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE) | |
{ | |
/*Stop Encoding/Decoding*/ | |
hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; | |
/* Disable All Interrupts */ | |
__HAL_JPEG_DISABLE_IT(hjpeg,JPEG_INTERRUPT_MASK); | |
/* Disable All DMA requests */ | |
JPEG_DISABLE_DMA(hjpeg,JPEG_DMA_MASK); | |
hjpeg->State= HAL_JPEG_STATE_READY; | |
hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; | |
HAL_JPEG_ErrorCallback(hjpeg); | |
} | |
} | |
/** | |
* @brief DMA output Abort callback | |
* @param hdma: pointer to a DMA_HandleTypeDef structure. | |
* @retval None | |
*/ | |
static void JPEG_DMAOutAbortCallback(DMA_HandleTypeDef *hdma) | |
{ | |
JPEG_HandleTypeDef* hjpeg = (JPEG_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; | |
if((hjpeg->Context & JPEG_CONTEXT_ENDING_DMA) != 0) | |
{ | |
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; | |
uint32_t *tableAddress = (uint32_t *)hjpeg->Instance->QMEM0; | |
i = 0; | |
while( i < JPEG_QUANT_TABLE_SIZE) | |
{ | |
quantRow = *tableAddress; | |
for(j=0; j<4; j++) | |
{ | |
quantVal = (quantRow >> (8 * j)) & 0xFF; | |
if(quantVal == 1) | |
{ | |
/* if Quantization value = 1 then quality is 100%*/ | |
quality += 100; | |
} | |
else | |
{ | |
/* Note that the quantization coefficients must be specified in the table in zigzag order */ | |
scale = (quantVal*100)/((uint32_t) JPEG_LUM_QuantTable[JPEG_ZIGZAG_ORDER[i+j]]); | |
if(scale <= 100) | |
{ | |
quality += (200 - scale)/2; | |
} | |
else | |
{ | |
quality += 5000/scale; | |
} | |
} | |
} | |
i += 4; | |
tableAddress ++; | |
} | |
return (quality/((uint32_t)64)); | |
} | |
/** | |
* @} | |
*/ | |
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */ | |
#endif /* HAL_JPEG_MODULE_ENABLED */ | |
/** | |
* @} | |
*/ | |
/** | |
* @} | |
*/ | |
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |