diff --git a/AlifSemiconductor.AzureRTOS.pdsc b/AlifSemiconductor.AzureRTOS.pdsc index ede2e27..619f83f 100644 --- a/AlifSemiconductor.AzureRTOS.pdsc +++ b/AlifSemiconductor.AzureRTOS.pdsc @@ -13,6 +13,10 @@ --> + + - update sample apps + + - Initial Release @@ -373,6 +377,8 @@ + + @@ -382,18 +388,21 @@ + - + + + diff --git a/NETX/driver/Inc/mac_hw.h b/NETX/driver/Inc/mac_hw.h index a74fcae..1938768 100644 --- a/NETX/driver/Inc/mac_hw.h +++ b/NETX/driver/Inc/mac_hw.h @@ -72,6 +72,7 @@ typedef struct { uint32_t tx_descs_in_use; /**< Number of tx descriptors in use by the hardware */ eth_config config; /**< Configuration information (Speed/Duplex/Autonegotiation). */ uint32_t rx_buf_size; /**< DMA rx buf size to be used */ + uint8_t irq_priority; /**< priority of the Ethernet MAC IRQ. */ } MAC_DEV; /** diff --git a/NETX/driver/Src/nx_eth_mac.c b/NETX/driver/Src/nx_eth_mac.c index fa6acf9..3300dfc 100644 --- a/NETX/driver/Src/nx_eth_mac.c +++ b/NETX/driver/Src/nx_eth_mac.c @@ -80,6 +80,7 @@ static MAC_DEV mac0 = { .speed = ETH_SPEED_CONFIG, .duplex = ETH_DUPLEX_CONFIG, }, + .irq_priority = RTE_ETH_MAC_IRQ_PRIORITY, }; /** \brief Driver instance */ @@ -1484,7 +1485,7 @@ MAC_DEV *dev = nx_mac_driver -> nx_driver_dev; /* Clear pending interrupt requests */ NVIC_ClearPendingIRQ(dev -> irq); /* Set priority and enable interrupts */ - NVIC_SetPriority(dev -> irq, 1); + NVIC_SetPriority(dev -> irq, dev -> irq_priority); NVIC_EnableIRQ(dev -> irq); /* Create event flags to signal the PHY poll events */ diff --git a/THREADX/samples/ADC_Click_Board_testapp.c b/THREADX/samples/ADC_Click_Board_testapp.c new file mode 100644 index 0000000..6d42165 --- /dev/null +++ b/THREADX/samples/ADC_Click_Board_testapp.c @@ -0,0 +1,283 @@ +/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved. + * Use, distribution and modification of this code is permitted under the + * terms stated in the Alif Semiconductor Software License Agreement + * + * You should have received a copy of the Alif Semiconductor Software + * License Agreement with this file. If not, please write to: + * contact@alifsemi.com, or visit: https://alifsemi.com/license + */ +/**************************************************************************//** + * @file : ADC_Click_Board_testapp.c + * @author : Prabhakar kumar + * @email : prabhakar.kumar@alifsemi.com + * @version : V1.0.0 + * @date : 15-sept-2023 + * @brief : Testapp demo application code click board analog input + * - Internal input analog signal corresponding output is digital value. + * - the input from the Click Board (CLICK_ANA) is internally connected to + * the ADC121 instance channel_0(j11 Pin 8). + * - the converted digital value are stored in user provided memory + * address. + * + * Hardware Connection: + * Connect MIKROE Click board J29 and J30 for input. + * @note CLICK_ANA is then connected to the voltage level translator + ******************************************************************************/ + +/* System Includes */ +#include +#include "tx_api.h" +#include "system_utils.h" + +/* include for ADC Driver */ +#include "Driver_ADC.h" + +/* PINMUX include */ +#include "pinconf.h" + +#include "se_services_port.h" +#include "RTE_Components.h" +#if defined(RTE_Compiler_IO_STDOUT) +#include "retarget_stdout.h" +#endif /* RTE_Compiler_IO_STDOUT */ + +/* single shot conversion scan use ARM_ADC_SINGLE_SHOT_CH_CONV*/ + +#define ADC_CONVERSION ARM_ADC_SINGLE_SHOT_CH_CONV + +/* Instance for ADC12 */ +extern ARM_DRIVER_ADC Driver_ADC121; +static ARM_DRIVER_ADC *ADCdrv = &Driver_ADC121; + +#define CLICK_BOARD_INPUT ARM_ADC_CHANNEL_0 +#define NUM_CHANNELS (8) + +void adc_click_board_demo(ULONG thread_input); + +/* Define the ThreadX object control blocks... */ +#define DEMO_STACK_SIZE 1024 +#define TX_ADC_INT_AVG_SAMPLE_RDY 0x01 + +TX_THREAD adc_thread; +TX_EVENT_FLAGS_GROUP event_flags_adc; + +/* Demo purpose adc_sample*/ +UINT adc_sample[NUM_CHANNELS]; + +volatile UINT num_samples = 0; + +/** + * @fn static int32_t pinmux_config(void) + * @brief ADC potentiometer pinmux configuration + * @retval execution status. + */ +static int32_t pinmux_config(void) +{ + INT ret = 0U; + + ret = pinconf_set(PORT_0, PIN_7, PINMUX_ALTERNATE_FUNCTION_7, + PADCTRL_READ_ENABLE ); + if (ret) + { + /* failed while configuring the PIMUX */ + return ret; + } + + return ret; +} + +/* + * @func : void adc_conversion_callback(uint32_t event, uint8_t channel, uint32_t sample_output) + * @brief : adc conversion isr callback + * @return : NONE +*/ +static void adc_conversion_callback(uint32_t event, uint8_t channel, uint32_t sample_output) +{ + if (event & ARM_ADC_EVENT_CONVERSION_COMPLETE) + { + num_samples += 1; + + /* Store the value for the respective channels */ + adc_sample[channel] = sample_output; + /* Sample ready Wake up Thread. */ + tx_event_flags_set(&event_flags_adc, TX_ADC_INT_AVG_SAMPLE_RDY, TX_OR); + } +} + +/** + * @func : void adc_click_board_demo(ULONG thread_input) + * @brief : ADC Click Board demo + * - test to verify the click board analog input of adc. + * - Internal input of click board in analog signal corresponding + * output is digital value. + * - converted value is the allocated user memory address. + * @return : NONE +*/ +void adc_click_board_demo(ULONG thread_input) +{ + INT ret = 0; + ULONG events = 0; + UINT error_code = SERVICES_REQ_SUCCESS; + UINT service_error_code; + ARM_DRIVER_VERSION version; + + (void) thread_input; + + /* Initialize the SE services */ + se_services_port_init(); + + /* enable the 160 MHz clock */ + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, + /*clock_enable_t*/ CLKEN_CLK_160M, + /*bool enable */ true, + &service_error_code); + if (error_code) + { + printf("SE Error: 160 MHz clk enable = %d\n", error_code); + return; + } + + printf("\t\t\n >>> ADC demo starting up!!! <<< \r\n"); + + version = ADCdrv->GetVersion(); + printf("\r\n ADC version api:%X driver:%X...\r\n",version.api, version.drv); + + /* PINMUX */ + ret = pinmux_config(); + if (ret != 0) + { + printf("Error in pin-mux configuration\n"); + return; + } + + /* Initialize ADC driver */ + ret = ADCdrv->Initialize(adc_conversion_callback); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC init failed\n"); + return; + } + + /* Power control ADC */ + ret = ADCdrv->PowerControl(ARM_POWER_FULL); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC Power up failed\n"); + goto error_uninitialize; + } + + /* set conversion mode */ + ret = ADCdrv->Control(ARM_ADC_CONVERSION_MODE_CTRL, ADC_CONVERSION); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC select conversion mode failed\n"); + goto error_poweroff; + } + + /* set initial channel */ + ret = ADCdrv->Control(ARM_ADC_CHANNEL_INIT_VAL, CLICK_BOARD_INPUT); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC channel init failed\n"); + goto error_poweroff; + } + + printf(">>> Allocated memory buffer Address is 0x%X <<<\n",(uint32_t)(adc_sample + CLICK_BOARD_INPUT)); + /* Start ADC */ + ret = ADCdrv->Start(); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC Start failed\n"); + goto error_poweroff; + } + + /* wait for timeout */ + while(num_samples == 0); + + /* wait till conversion comes ( isr callback ) */ + ret = tx_event_flags_get(&event_flags_adc, TX_ADC_INT_AVG_SAMPLE_RDY, + TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + if (ret != TX_SUCCESS) { + printf("Error: ADC tx_event_flags_get\n"); + goto error_poweroff; + } + + printf("\n Click Board input conversion completed \n"); + + /* Stop ADC */ + ret = ADCdrv->Stop(); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC Stop failed\n"); + goto error_poweroff; + } + + printf("\n ---END--- \r\n wait forever >>> \n"); + while(1); + +error_poweroff: + + /* Power off ADC peripheral */ + ret = ADCdrv->PowerControl(ARM_POWER_OFF); + if (ret != ARM_DRIVER_OK) + { + printf("\r\n Error: ADC Power OFF failed.\r\n"); + } + +error_uninitialize: + + /* Un-initialize ADC driver */ + ret = ADCdrv->Uninitialize(); + if (ret != ARM_DRIVER_OK) + { + printf("\r\n Error: ADC Uninitialize failed.\r\n"); + } + /* disable the 160 MHz clock */ + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, + /*clock_enable_t*/ CLKEN_CLK_160M, + /*bool enable */ false, + &service_error_code); + if (error_code) + { + printf("SE Error: 160 MHz clk disable = %d\n", error_code); + return; + } + + printf("\r\n ADC demo exiting...\r\n"); +} + +/* Define main entry point. */ +int main() +{ + #if defined(RTE_Compiler_IO_STDOUT_User) + int32_t ret; + ret = stdout_init(); + if(ret != ARM_DRIVER_OK) + { + while(1) + { + } + } + #endif + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + +/* Define what the initial system looks like. */ +void tx_application_define(void *first_unused_memory) +{ + INT status; + + /* Create the event flags group used by ADC thread */ + status = tx_event_flags_create(&event_flags_adc, "event flags ADC"); + if (status != TX_SUCCESS) + { + printf("Could not create event flags\n"); + return; + } + + /* Create the main thread. */ + status = tx_thread_create(&adc_thread, "adc_thread", adc_click_board_demo, 0, + first_unused_memory, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + if (status != TX_SUCCESS) + { + printf("Could not create thread\n"); + return; + } +} diff --git a/THREADX/samples/ADC_Potentiometer_testapp.c b/THREADX/samples/ADC_Potentiometer_testapp.c new file mode 100644 index 0000000..f825fec --- /dev/null +++ b/THREADX/samples/ADC_Potentiometer_testapp.c @@ -0,0 +1,284 @@ +/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved. + * Use, distribution and modification of this code is permitted under the + * terms stated in the Alif Semiconductor Software License Agreement + * + * You should have received a copy of the Alif Semiconductor Software + * License Agreement with this file. If not, please write to: + * contact@alifsemi.com, or visit: https://alifsemi.com/license + */ +/**************************************************************************//** + * @file : ADC_Potentiometer_testapp.c + * @author : Prabhakar kumar + * @email : prabhakar.kumar@alifsemi.com + * @version : V1.0.0 + * @date : 15-SEPT-2023 + * @brief : Testapp demo application code for potentiometer input + * - Internal input of potentiometer in analog signal corresponding + * output is digital value. + * - the input from the potentiometer is internally connected to + * the ADC121 instance channel_1(j11 Pin 10). + * - the converted digital value are stored in user provided memory + * address. + * + * Hardware Connection: + * Analog variable register R53 is connected internally to the ADC121 + * channel_1 which volatge vary from 0 to 1.8V + ******************************************************************************/ + +/* System Includes */ +#include +#include "tx_api.h" +#include "system_utils.h" + +/* include for ADC Driver */ +#include "Driver_ADC.h" + +/* PINMUX include */ +#include "pinconf.h" + +#include "se_services_port.h" +#include "RTE_Components.h" +#if defined(RTE_Compiler_IO_STDOUT) +#include "retarget_stdout.h" +#endif /* RTE_Compiler_IO_STDOUT */ + +/* single shot conversion scan use ARM_ADC_SINGLE_SHOT_CH_CONV*/ + +#define ADC_CONVERSION ARM_ADC_SINGLE_SHOT_CH_CONV + +/* Instance for ADC12 */ +extern ARM_DRIVER_ADC Driver_ADC121; +static ARM_DRIVER_ADC *ADCdrv = &Driver_ADC121; + +#define POTENTIOMETER ARM_ADC_CHANNEL_1 +#define NUM_CHANNELS (8) + +void adc_potentiometer_demo(ULONG thread_input); + +/* Define the ThreadX object control blocks... */ +#define DEMO_STACK_SIZE 1024 +#define TX_ADC_INT_AVG_SAMPLE_RDY 0x01 + +TX_THREAD adc_thread; +TX_EVENT_FLAGS_GROUP event_flags_adc; + +/* Demo purpose adc_sample*/ +UINT adc_sample[NUM_CHANNELS]; + +volatile UINT num_samples = 0; + +/** + * @fn static int32_t pinmux_config(void) + * @brief ADC potentiometer pinmux configuration + * @retval execution status. + */ +static int32_t pinmux_config(void) +{ + INT ret = 0U; + + ret = pinconf_set(PORT_0, PIN_7, PINMUX_ALTERNATE_FUNCTION_7, + PADCTRL_READ_ENABLE ); + if (ret) + { + /* failed while configuring the PIMUX */ + return ret; + } + + return ret; +} + +/* + * @func : void adc_conversion_callback(uint32_t event, uint8_t channel, uint32_t sample_output) + * @brief : adc conversion isr callback + * @return : NONE +*/ +static void adc_conversion_callback(uint32_t event, uint8_t channel, uint32_t sample_output) +{ + if (event & ARM_ADC_EVENT_CONVERSION_COMPLETE) + { + num_samples += 1; + + /* Store the value for the respected channels */ + adc_sample[channel] = sample_output; + /* Sample ready Wake up Thread. */ + tx_event_flags_set(&event_flags_adc, TX_ADC_INT_AVG_SAMPLE_RDY, TX_OR); + } +} + +/** + * @func : void adc_potentiometer_demo(ULONG thread_input) + * @brief : ADC Potentiometer demo + * - test to verify the potentiometer analog input + * - Internal input of potentiometer in analog signal corresponding + * output is digital value. + * - converted value is the allocated user memory address. + * @return : NONE +*/ +void adc_potentiometer_demo(ULONG thread_input) +{ + INT ret = 0; + ULONG events = 0; + UINT error_code = SERVICES_REQ_SUCCESS; + UINT service_error_code; + ARM_DRIVER_VERSION version; + + (void) thread_input; + + /* Initialize the SE services */ + se_services_port_init(); + + /* enable the 160 MHz clock */ + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, + /*clock_enable_t*/ CLKEN_CLK_160M, + /*bool enable */ true, + &service_error_code); + if (error_code) + { + printf("SE Error: 160 MHz clk enable = %d\n", error_code); + return; + } + + printf("\t\t\n >>> ADC demo starting up!!! <<< \r\n"); + + version = ADCdrv->GetVersion(); + printf("\r\n ADC version api:%X driver:%X...\r\n",version.api, version.drv); + + /* PINMUX */ + ret = pinmux_config(); + if (ret != 0) + { + printf("Error in pin-mux configuration\n"); + return; + } + + /* Initialize ADC driver */ + ret = ADCdrv->Initialize(adc_conversion_callback); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC init failed\n"); + goto error_uninitialize; + } + + /* Power control ADC */ + ret = ADCdrv->PowerControl(ARM_POWER_FULL); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC Power up failed\n"); + goto error_uninitialize; + } + + /* set conversion mode */ + ret = ADCdrv->Control(ARM_ADC_CONVERSION_MODE_CTRL, ADC_CONVERSION); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC select conversion mode failed\n"); + goto error_poweroff; + } + + /* set initial channel */ + ret = ADCdrv->Control(ARM_ADC_CHANNEL_INIT_VAL, POTENTIOMETER); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC channel init failed\n"); + goto error_poweroff; + } + + printf(">>> Allocated memory buffer Address is 0x%X <<<\n",(uint32_t)(adc_sample + POTENTIOMETER)); + /* Start ADC */ + ret = ADCdrv->Start(); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC Start failed\n"); + goto error_poweroff; + } + + /* wait for timeout */ + while (num_samples == 0); + + /* wait till conversion comes ( isr callback ) */ + ret = tx_event_flags_get(&event_flags_adc, TX_ADC_INT_AVG_SAMPLE_RDY, + TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + if (ret != TX_SUCCESS) { + printf("Error: ADC tx_event_flags_get\n"); + goto error_poweroff; + } + + printf("\n Potentiometer conversion completed \n"); + + /* Stop ADC */ + ret = ADCdrv->Stop(); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC Stop failed\n"); + goto error_poweroff; + } + + printf("\n ---END--- \r\n wait forever >>> \n"); + while(1); + +error_poweroff: + + /* Power off ADC peripheral */ + ret = ADCdrv->PowerControl(ARM_POWER_OFF); + if (ret != ARM_DRIVER_OK) + { + printf("\r\n Error: ADC Power OFF failed.\r\n"); + } + +error_uninitialize: + + /* Un-initialize ADC driver */ + ret = ADCdrv->Uninitialize(); + if (ret != ARM_DRIVER_OK) + { + printf("\r\n Error: ADC Uninitialize failed.\r\n"); + } + /* disable the 160MHz clock */ + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, + /*clock_enable_t*/ CLKEN_CLK_160M, + /*bool enable */ false, + &service_error_code); + if (error_code) + { + printf("SE Error: 160 MHz clk disable = %d\n", error_code); + return; + } + + printf("\r\n ADC demo exiting...\r\n"); +} + +/* Define main entry point. */ +int main() +{ + #if defined(RTE_Compiler_IO_STDOUT_User) + int32_t ret; + ret = stdout_init(); + if(ret != ARM_DRIVER_OK) + { + while(1) + { + } + } + #endif + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + +/* Define what the initial system looks like. */ +void tx_application_define(void *first_unused_memory) +{ + INT status; + + /* Create the event flags group used by ADC thread */ + status = tx_event_flags_create(&event_flags_adc, "event flags ADC"); + if (status != TX_SUCCESS) + { + printf("Could not create event flags\n"); + return; + } + + /* Create the main thread. */ + status = tx_thread_create(&adc_thread, "adc_thread", adc_potentiometer_demo, 0, + first_unused_memory, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + if (status != TX_SUCCESS) + { + printf("Could not create thread\n"); + return; + } +} diff --git a/THREADX/samples/ARX3A0_Camera_Sensor_testApp.c b/THREADX/samples/ARX3A0_Camera_Sensor_testApp.c index 22c576d..84567cf 100644 --- a/THREADX/samples/ARX3A0_Camera_Sensor_testApp.c +++ b/THREADX/samples/ARX3A0_Camera_Sensor_testApp.c @@ -561,6 +561,15 @@ void camera_demo_thread_entry(ULONG thread_input) printf("\r\n Error: CAMERA image conversion failed.\r\n"); return; } + + else + { + printf("\n Bayer to RGB Converted Tiff Color Image Memory Address is :"); + printf("\n \t starting_addr: 0x%X \r\n \t ending_addr : 0x%X\n", \ + (uint32_t) bayer_to_rgb_buffer_pool, + (uint32_t) (bayer_to_rgb_buffer_pool + BAYER_TO_RGB_BUFFER_POOL_SIZE - 1)); + } + #endif /* end of IMAGE_CONVERSION_BAYER_TO_RGB_EN */ /* How to dump captured/converted image data from memory address? diff --git a/THREADX/samples/CANFD_Bus_Monitor.c b/THREADX/samples/CANFD_Bus_Monitor.c index 5c72e1b..ee5f61e 100644 --- a/THREADX/samples/CANFD_Bus_Monitor.c +++ b/THREADX/samples/CANFD_Bus_Monitor.c @@ -75,26 +75,27 @@ /* Define the ThreadX object control blocks... */ #define THREAD_STACK_SIZE 1024U -TX_THREAD canfd_thread; -TX_EVENT_FLAGS_GROUP event_flags_canfd; +static TX_THREAD canfd_thread; +static TX_EVENT_FLAGS_GROUP event_flags_canfd; /* CANFD instance object */ extern ARM_DRIVER_CAN Driver_CANFD; -static ARM_DRIVER_CAN* CANFD_instance = &Driver_CANFD; +static ARM_DRIVER_CAN* CANFD_instance = &Driver_CANFD; /* File Global variables */ -volatile bool is_msg_read = false; -volatile bool bus_error = false; -volatile bool bus_off = false; -volatile bool passive_mode = false; -uint8_t rx_obj_id = 255U; -ARM_CAN_MSG_INFO rx_msg_header; -volatile uint8_t rx_msg_size = 8U; -uint8_t rx_data[CANFD_MAX_MSG_SIZE + 1U]; +static volatile bool is_msg_read = false; +static volatile bool bus_error = false; +static volatile bool bus_off = false; +static volatile bool passive_mode = false; +static uint8_t rx_obj_id = 255U; +static ARM_CAN_MSG_INFO rx_msg_header; +static volatile uint8_t rx_msg_size = 8U; +static uint8_t rx_data[CANFD_MAX_MSG_SIZE + 1U]; /* A map between Data length code to the payload size */ -const uint8_t canfd_len_dlc_map[0x10U] = - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U}; +static const uint8_t canfd_len_dlc_map[0x10U] = + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, + 12U, 16U, 20U, 24U, 32U, 48U, 64U}; /* Support functions */ static void canfd_process_rx_message(void); @@ -133,13 +134,13 @@ static int32_t pinmux_config(void) } /** - * @fn void cb_unit_event(uint32_t event) + * @fn static void cb_unit_event(uint32_t event) * @brief CANFD Callback function for events * @note none * @param event: CANFD event * @retval none */ -void cb_unit_event(uint32_t event) +static void cb_unit_event(uint32_t event) { if(event == ARM_CAN_EVENT_UNIT_ACTIVE) { @@ -169,16 +170,17 @@ void cb_unit_event(uint32_t event) } /** - * @fn void cb_object_event(uint32_t obj_idx, uint32_t event) + * @fn static void cb_object_event(uint32_t obj_idx, uint32_t event) * @brief CANFD Callback function for particular object events * @note none * @param obj_idx : Object ID * @param event : CANFD event * @retval none */ -void cb_object_event(uint32_t obj_idx, uint32_t event) +static void cb_object_event(uint32_t obj_idx, uint32_t event) { - if((event & ARM_CAN_EVENT_RECEIVE) || (event & ARM_CAN_EVENT_RECEIVE_OVERRUN)) + if((event & ARM_CAN_EVENT_RECEIVE) || + (event & ARM_CAN_EVENT_RECEIVE_OVERRUN)) { /* Sets msg_rx_complete if the Receive Object matches */ if(obj_idx == rx_obj_id) @@ -193,13 +195,13 @@ void cb_object_event(uint32_t obj_idx, uint32_t event) } /** - * @fn void canfd_lom_demo_task(ULONG thread_input) + * @fn static void canfd_lom_demo_task(ULONG thread_input) * @brief CANFD Listen only mode Demo * @note none. * @param thread_input : Input for thread * @retval none */ -void canfd_lom_demo_task(ULONG thread_input) +static void canfd_lom_demo_task(ULONG thread_input) { int32_t ret_val = ARM_DRIVER_OK; UINT event_ret = 0U; @@ -210,6 +212,8 @@ void canfd_lom_demo_task(ULONG thread_input) uint32_t error_code = 0U; uint32_t service_error_code = 0U; + ARG_UNUSED(thread_input); + /* Initialize the SE services */ se_services_port_init(); @@ -446,8 +450,8 @@ void tx_application_define(void *first_unused_memory) { UINT status; - /* Put system definition stuff in here, e.g. thread creates and other assorted - create information. */ + /* Put system definition stuff in here, e.g. thread creates and + other assorted create information. */ /* Create the event flags group used by CANFD thread */ status = tx_event_flags_create(&event_flags_canfd, "CANFD Events"); @@ -459,8 +463,8 @@ void tx_application_define(void *first_unused_memory) /* Create the main thread. */ status = tx_thread_create(&canfd_thread, "CANFD_LOM", canfd_lom_demo_task, - 0U, first_unused_memory, THREAD_STACK_SIZE, 1U, 1U, - TX_NO_TIME_SLICE, TX_AUTO_START); + 0U, first_unused_memory, THREAD_STACK_SIZE, + 1U, 1U, TX_NO_TIME_SLICE, TX_AUTO_START); if(status != TX_SUCCESS) { printf("Unable to Create LOM Task\n"); @@ -468,13 +472,13 @@ void tx_application_define(void *first_unused_memory) } } /** - * @fn void canfd_check_error(void) + * @fn static void canfd_check_error(void) * @brief Checks for the errors in CANFD * @note none * @param none * @retval none */ -void canfd_check_error(void) +static void canfd_check_error(void) { ARM_CAN_STATUS cur_sts; @@ -487,7 +491,8 @@ void canfd_check_error(void) { /* Reading arrived CANFD Message */ if(CANFD_instance->MessageRead(rx_obj_id, &rx_msg_header, - rx_data, rx_msg_size) != ARM_DRIVER_OK) + rx_data, + rx_msg_size) != ARM_DRIVER_OK) { printf("Error: Message reception failed\r\n"); } @@ -500,7 +505,8 @@ void canfd_check_error(void) } else { - printf("Error in CANFD-->Error code: %d\r\n", cur_sts.last_error_code); + printf("Error in CANFD-->Error code: %d\r\n", + cur_sts.last_error_code); } bus_error = false; } @@ -518,13 +524,13 @@ void canfd_check_error(void) } /** - * @fn void canfd_process_rx_message(void) + * @fn static void canfd_process_rx_message(void) * @brief Processes the received messages * @note none * @param none * @retval none */ -void canfd_process_rx_message(void) +static void canfd_process_rx_message(void) { uint8_t iter = 0U; diff --git a/THREADX/samples/CANFD_Ext_Loopback.c b/THREADX/samples/CANFD_Ext_Loopback.c index 064cc0f..9a2ef42 100644 --- a/THREADX/samples/CANFD_Ext_Loopback.c +++ b/THREADX/samples/CANFD_Ext_Loopback.c @@ -90,31 +90,33 @@ typedef enum _CANFD_FRAME /* Define the ThreadX object control blocks... */ #define THREAD_STACK_SIZE 1024U -TX_THREAD canfd_thread; -TX_EVENT_FLAGS_GROUP event_flags_canfd; +static TX_THREAD canfd_thread; +static TX_EVENT_FLAGS_GROUP event_flags_canfd; /* CANFD instance object */ extern ARM_DRIVER_CAN Driver_CANFD; -static ARM_DRIVER_CAN* CANFD_instance = &Driver_CANFD; +static ARM_DRIVER_CAN* CANFD_instance = &Driver_CANFD; /* File Global variables */ -volatile bool bus_error = false; -volatile bool passive_mode = false; -volatile bool rx_buf_overrun = false; -bool stop_execution = false; -volatile bool rx_msg_error = false; -uint8_t tx_obj_id = 255U; -uint8_t rx_obj_id = 255U; -ARM_CAN_MSG_INFO tx_msg_header; -ARM_CAN_MSG_INFO rx_msg_header; -uint8_t tx_msg_size = 0U; -volatile uint8_t rx_msg_size = 0U; -uint8_t tx_data[CANFD_MAX_MSG_SIZE + 1U] = "!!!!!!***** CANFD TESTAPP Message Communication Test *****!!!!!!"; -uint8_t rx_data[CANFD_MAX_MSG_SIZE + 1U]; +static volatile bool bus_error = false; +static volatile bool passive_mode = false; +static volatile bool rx_buf_overrun = false; +static bool stop_execution = false; +static volatile bool rx_msg_error = false; +static uint8_t tx_obj_id = 255U; +static uint8_t rx_obj_id = 255U; +static ARM_CAN_MSG_INFO tx_msg_header; +static ARM_CAN_MSG_INFO rx_msg_header; +static uint8_t tx_msg_size = 0U; +static volatile uint8_t rx_msg_size = 0U; +static uint8_t tx_data[CANFD_MAX_MSG_SIZE + 1U] = + "!!!!!!***** CANFD TESTAPP Message Communication Test *****!!!!!!"; +static uint8_t rx_data[CANFD_MAX_MSG_SIZE + 1U]; /* A map between Data length code to the payload size */ -const uint8_t canfd_len_dlc_map[0x10U] = - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U}; +static const uint8_t canfd_len_dlc_map[0x10U] = + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, + 12U, 16U, 20U, 24U, 32U, 48U, 64U}; /* Support functions */ static bool canfd_process_rx_message(void); @@ -154,13 +156,13 @@ static int32_t pinmux_config(void) } /** - * @fn void cb_unit_event(uint32_t event) + * @fn static void cb_unit_event(uint32_t event) * @brief CANFD Callback function for events * @note none * @param event: CANFD event * @retval none */ -void cb_unit_event(uint32_t event) +static void cb_unit_event(uint32_t event) { if(event == ARM_CAN_EVENT_UNIT_ACTIVE) { @@ -190,23 +192,25 @@ void cb_unit_event(uint32_t event) } /** - * @fn void cb_object_event(uint32_t obj_idx, uint32_t event) + * @fn static void cb_object_event(uint32_t obj_idx, uint32_t event) * @brief CANFD Callback function for particular object events * @note none * @param obj_idx : Object ID * @param event : CANFD event * @retval none */ -void cb_object_event(uint32_t obj_idx, uint32_t event) +static void cb_object_event(uint32_t obj_idx, uint32_t event) { - if((event & ARM_CAN_EVENT_RECEIVE) || (event & ARM_CAN_EVENT_RECEIVE_OVERRUN)) + if((event & ARM_CAN_EVENT_RECEIVE) || + (event & ARM_CAN_EVENT_RECEIVE_OVERRUN)) { /* Invokes Message Read function if the Receive Object matches */ if(obj_idx == rx_obj_id) { /* Reading arrived CAN Message */ if(CANFD_instance->MessageRead(obj_idx, &rx_msg_header, - rx_data, rx_msg_size) != ARM_DRIVER_OK) + rx_data, + rx_msg_size) != ARM_DRIVER_OK) { rx_msg_error = true; } @@ -223,13 +227,13 @@ void cb_object_event(uint32_t obj_idx, uint32_t event) } /** - * @fn void canfd_lbe_demo_task(ULONG thread_input) + * @fn static void canfd_lbe_demo_task(ULONG thread_input) * @brief CANFD External Loopback Demo * @note none * @param thread_input : Input for thread * @retval none */ -void canfd_lbe_demo_task(ULONG thread_input) +static void canfd_lbe_demo_task(ULONG thread_input) { CANFD_FRAME msg_type = CANFD_FRAME_STD_ID_CLASSIC_DATA; int32_t ret_val = ARM_DRIVER_OK; @@ -242,6 +246,8 @@ void canfd_lbe_demo_task(ULONG thread_input) uint32_t error_code = 0U; uint32_t service_error_code = 0U; + ARG_UNUSED(thread_input); + /* Initialize the SE services */ se_services_port_init(); @@ -422,7 +428,8 @@ void canfd_lbe_demo_task(ULONG thread_input) /* wait for receive/error callback. */ event_ret = tx_event_flags_get(&event_flags_canfd, CANFD_ALL_NOTIFICATIONS, - TX_OR_CLEAR, &task_notified_value, + TX_OR_CLEAR, + &task_notified_value, TX_WAIT_FOREVER); if(event_ret != TX_SUCCESS) { @@ -526,8 +533,8 @@ int main() void tx_application_define(void *first_unused_memory) { UINT status; - /* Put system definition stuff in here, e.g. thread creates and other assorted - create information. */ + /* Put system definition stuff in here, e.g. thread creates and + other assorted create information. */ /* Create the event flags group used by CANFD thread */ status = tx_event_flags_create(&event_flags_canfd, "CANFD Events"); @@ -539,8 +546,8 @@ void tx_application_define(void *first_unused_memory) /* Create the main thread. */ status = tx_thread_create(&canfd_thread, "CANFD_LBEM", canfd_lbe_demo_task, - 0U, first_unused_memory, THREAD_STACK_SIZE, 1U, 1U, - TX_NO_TIME_SLICE, TX_AUTO_START); + 0U, first_unused_memory, THREAD_STACK_SIZE, + 1U, 1U, TX_NO_TIME_SLICE, TX_AUTO_START); if(status != TX_SUCCESS) { printf("Unable to Create LBE Task\n"); @@ -549,13 +556,13 @@ void tx_application_define(void *first_unused_memory) } /** - * @fn void canfd_check_error(void) + * @fn static void canfd_check_error(void) * @brief Checks for the errors in CANFD * @note none * @param none * @retval none */ -void canfd_check_error(void) +static void canfd_check_error(void) { ARM_CAN_STATUS cur_sts; @@ -580,13 +587,13 @@ void canfd_check_error(void) } /** - * @fn bool canfd_process_rx_message(void) + * @fn static bool canfd_process_rx_message(void) * @brief Processes the received messages * @note none * @param none * @retval none */ -bool canfd_process_rx_message(void) +static bool canfd_process_rx_message(void) { uint8_t iter = 0U; @@ -626,7 +633,8 @@ bool canfd_process_rx_message(void) } printf("Id:%lu, Len:%d:\r\n Data:", - (rx_msg_header.id & (~ARM_CAN_ID_IDE_Msk)), rx_msg_size); + (rx_msg_header.id & (~ARM_CAN_ID_IDE_Msk)), + rx_msg_size); for(iter = 0; iter < rx_msg_size; iter++) { printf("%c", rx_data[iter]); @@ -658,19 +666,17 @@ bool canfd_process_rx_message(void) } /** - * @fn bool canfd_transmit_message(CANFD_FRAME msg_type) + * @fn static bool canfd_transmit_message(CANFD_FRAME msg_type) * @brief Prepares and sends message * @note none * @param msg_type : Type of msg to send * @retval none */ -bool canfd_transmit_message(const CANFD_FRAME msg_type) +static bool canfd_transmit_message(const CANFD_FRAME msg_type) { - uint32_t status = ARM_DRIVER_OK; - uint8_t iter; + int32_t status = ARM_DRIVER_OK; + uint8_t iter = 0U; - /* If the previous message is successfully sent, - * then prepare and transmit next message */ switch(msg_type) { case CANFD_FRAME_STD_ID_CLASSIC_DATA: diff --git a/THREADX/samples/CANFD_Int_Loopback.c b/THREADX/samples/CANFD_Int_Loopback.c index 6f12a44..974ab87 100644 --- a/THREADX/samples/CANFD_Int_Loopback.c +++ b/THREADX/samples/CANFD_Int_Loopback.c @@ -91,30 +91,32 @@ typedef enum _CANFD_FRAME /* Define the ThreadX object control blocks... */ #define THREAD_STACK_SIZE 1024U -TX_THREAD canfd_thread; -TX_EVENT_FLAGS_GROUP event_flags_canfd; +static TX_THREAD canfd_thread; +static TX_EVENT_FLAGS_GROUP event_flags_canfd; /* CANFD instance object */ extern ARM_DRIVER_CAN Driver_CANFD; -static ARM_DRIVER_CAN* CANFD_instance = &Driver_CANFD; +static ARM_DRIVER_CAN* CANFD_instance = &Driver_CANFD; /* File Global variables */ -volatile bool error_occurred = false; -volatile bool rx_buf_overrun = false; -bool stop_execution = false; -volatile bool rx_msg_error = false; -uint8_t tx_obj_id = 255U; -uint8_t rx_obj_id = 255U; -ARM_CAN_MSG_INFO tx_msg_header; -ARM_CAN_MSG_INFO rx_msg_header; -uint8_t tx_msg_size = 0U; -volatile uint8_t rx_msg_size = 0U; -uint8_t tx_data[CANFD_MAX_MSG_SIZE + 1U] = "!!!!!!***** CANFD TESTAPP Message Communication Test *****!!!!!!"; -uint8_t rx_data[CANFD_MAX_MSG_SIZE + 1U]; +static volatile bool error_occurred = false; +static volatile bool rx_buf_overrun = false; +static bool stop_execution = false; +static volatile bool rx_msg_error = false; +static uint8_t tx_obj_id = 255U; +static uint8_t rx_obj_id = 255U; +static ARM_CAN_MSG_INFO tx_msg_header; +static ARM_CAN_MSG_INFO rx_msg_header; +static uint8_t tx_msg_size = 0U; +static volatile uint8_t rx_msg_size = 0U; +static uint8_t tx_data[CANFD_MAX_MSG_SIZE + 1U] = + "!!!!!!***** CANFD TESTAPP Message Communication Test *****!!!!!!"; +static uint8_t rx_data[CANFD_MAX_MSG_SIZE + 1U]; /* A map between Data length code to the payload size */ -const uint8_t canfd_len_dlc_map[0x10U] = - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U}; +static const uint8_t canfd_len_dlc_map[0x10U] = + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, + 12U, 16U, 20U, 24U, 32U, 48U, 64U}; /* Support functions */ static bool canfd_process_rx_message(void); @@ -154,13 +156,13 @@ static int32_t pinmux_config(void) } /** - * @fn void cb_unit_event(uint32_t event) + * @fn static void cb_unit_event(uint32_t event) * @brief CANFD Callback function for events * @note none * @param event: CANFD event * @retval none */ -void cb_unit_event(uint32_t event) +static void cb_unit_event(uint32_t event) { if(event == ARM_CAN_EVENT_UNIT_WARNING) { @@ -170,23 +172,25 @@ void cb_unit_event(uint32_t event) } /** - * @fn void cb_object_event(uint32_t obj_idx, uint32_t event) + * @fn static void cb_object_event(uint32_t obj_idx, uint32_t event) * @brief CANFD Callback function for particular object events * @note none * @param obj_idx : Object ID * @param event : CANFD event * @retval none */ -void cb_object_event(uint32_t obj_idx, uint32_t event) +static void cb_object_event(uint32_t obj_idx, uint32_t event) { - if((event & ARM_CAN_EVENT_RECEIVE) || (event & ARM_CAN_EVENT_RECEIVE_OVERRUN)) + if((event & ARM_CAN_EVENT_RECEIVE) || + (event & ARM_CAN_EVENT_RECEIVE_OVERRUN)) { /* Invokes Message Read function if the Receive Object matches */ if(obj_idx == rx_obj_id) { /* Reading arrived CAN Message */ if(CANFD_instance->MessageRead(obj_idx, &rx_msg_header, - rx_data, rx_msg_size) != ARM_DRIVER_OK) + rx_data, + rx_msg_size) != ARM_DRIVER_OK) { rx_msg_error = true; } @@ -203,13 +207,13 @@ void cb_object_event(uint32_t obj_idx, uint32_t event) } /** - * @fn void canfd_lbi_demo_task(ULONG thread_input) + * @fn static void canfd_lbi_demo_task(ULONG thread_input) * @brief CANFD Internal Loopback Demo * @note none * @param thread_input : Input for thread * @retval none */ -void canfd_lbi_demo_task(ULONG thread_input) +static void canfd_lbi_demo_task(ULONG thread_input) { CANFD_FRAME msg_type = CANFD_FRAME_STD_ID_CLASSIC_DATA; int32_t ret_val = ARM_DRIVER_OK; @@ -222,6 +226,8 @@ void canfd_lbi_demo_task(ULONG thread_input) uint32_t error_code = 0U; uint32_t service_error_code = 0U; + ARG_UNUSED(thread_input); + /* Initialize the SE services */ se_services_port_init(); @@ -403,7 +409,8 @@ void canfd_lbi_demo_task(ULONG thread_input) /* wait for receive/error callback. */ event_ret = tx_event_flags_get(&event_flags_canfd, CANFD_ALL_NOTIFICATIONS, - TX_OR_CLEAR, &task_notified_value, + TX_OR_CLEAR, + &task_notified_value, TX_WAIT_FOREVER); if(event_ret != TX_SUCCESS) { @@ -506,8 +513,8 @@ void tx_application_define(void *first_unused_memory) { UINT status; - /* Put system definition stuff in here, e.g. thread creates and other assorted - create information. */ + /* Put system definition stuff in here, e.g. thread creates and + other assorted create information. */ /* Create the event flags group used by CANFD thread */ status = tx_event_flags_create(&event_flags_canfd, "CANFD Events"); @@ -519,8 +526,8 @@ void tx_application_define(void *first_unused_memory) /* Create the main thread. */ status = tx_thread_create(&canfd_thread, "CANFD_LBIM", canfd_lbi_demo_task, - 0U, first_unused_memory, THREAD_STACK_SIZE, 1U, 1U, - TX_NO_TIME_SLICE, TX_AUTO_START); + 0U, first_unused_memory, THREAD_STACK_SIZE, + 1U, 1U, TX_NO_TIME_SLICE, TX_AUTO_START); if(status != TX_SUCCESS) { printf("Unable to Create LBI Task\n"); @@ -529,13 +536,13 @@ void tx_application_define(void *first_unused_memory) } /** - * @fn void canfd_check_error(void) + * @fn static void canfd_check_error(void) * @brief Checks for the errors in CANFD * @note none * @param none * @retval none */ -void canfd_check_error(void) +static void canfd_check_error(void) { ARM_CAN_STATUS cur_sts; if(error_occurred) @@ -550,13 +557,13 @@ void canfd_check_error(void) } /** - * @fn bool canfd_process_rx_message(void) + * @fn static bool canfd_process_rx_message(void) * @brief Processes the received messages * @note none * @param none * @retval none */ -bool canfd_process_rx_message(void) +static bool canfd_process_rx_message(void) { uint8_t iter = 0U; @@ -596,7 +603,8 @@ bool canfd_process_rx_message(void) } printf("Id:%lu, Len:%d:\r\n Data:", - (rx_msg_header.id & (~ARM_CAN_ID_IDE_Msk)), rx_msg_size); + (rx_msg_header.id & (~ARM_CAN_ID_IDE_Msk)), + rx_msg_size); for(iter = 0; iter < rx_msg_size; iter++) { printf("%c", rx_data[iter]); @@ -628,19 +636,17 @@ bool canfd_process_rx_message(void) } /** - * @fn bool canfd_transmit_message(CANFD_FRAME msg_type) + * @fn static bool canfd_transmit_message(CANFD_FRAME msg_type) * @brief Prepares and sends message * @note none * @param msg_type : Type of msg to send * @retval none */ -bool canfd_transmit_message(const CANFD_FRAME msg_type) +static bool canfd_transmit_message(const CANFD_FRAME msg_type) { - uint32_t status = ARM_DRIVER_OK; - uint8_t iter; + int32_t status = ARM_DRIVER_OK; + uint8_t iter = 0U; - /* If the previous message is successfully sent, - * then prepare and transmit next message */ switch(msg_type) { case CANFD_FRAME_STD_ID_CLASSIC_DATA: diff --git a/THREADX/samples/CANFD_NormalMode.c b/THREADX/samples/CANFD_NormalMode.c index 310c102..f687239 100644 --- a/THREADX/samples/CANFD_NormalMode.c +++ b/THREADX/samples/CANFD_NormalMode.c @@ -90,31 +90,33 @@ typedef enum _CANFD_FRAME /* Define the ThreadX object control blocks... */ #define THREAD_STACK_SIZE 1024U -TX_THREAD canfd_thread; -TX_EVENT_FLAGS_GROUP event_flags_canfd; +static TX_THREAD canfd_thread; +static TX_EVENT_FLAGS_GROUP event_flags_canfd; /* CANFD instance object */ extern ARM_DRIVER_CAN Driver_CANFD; -static ARM_DRIVER_CAN* CANFD_instance = &Driver_CANFD; +static ARM_DRIVER_CAN* CANFD_instance = &Driver_CANFD; /* File Global variables */ -volatile bool bus_error = false; -volatile bool passive_mode = false; -volatile bool rx_buf_overrun = false; -bool stop_execution = false; -volatile bool rx_msg_error = false; -uint8_t tx_obj_id = 255U; -uint8_t rx_obj_id = 255U; -ARM_CAN_MSG_INFO tx_msg_header; -ARM_CAN_MSG_INFO rx_msg_header; -uint8_t tx_msg_size = 0U; -volatile uint8_t rx_msg_size = 8U; -uint8_t tx_data[CANFD_MAX_MSG_SIZE + 1U] = "!!!!!!***** CANFD TESTAPP Message Communication Test *****!!!!!!"; -uint8_t rx_data[CANFD_MAX_MSG_SIZE + 1U]; +static volatile bool bus_error = false; +static volatile bool passive_mode = false; +static volatile bool rx_buf_overrun = false; +static bool stop_execution = false; +static volatile bool rx_msg_error = false; +static uint8_t tx_obj_id = 255U; +static uint8_t rx_obj_id = 255U; +static ARM_CAN_MSG_INFO tx_msg_header; +static ARM_CAN_MSG_INFO rx_msg_header; +static uint8_t tx_msg_size = 0U; +static volatile uint8_t rx_msg_size = 8U; +static uint8_t tx_data[CANFD_MAX_MSG_SIZE + 1U] = + "!!!!!!***** CANFD TESTAPP Message Communication Test *****!!!!!!"; +static uint8_t rx_data[CANFD_MAX_MSG_SIZE + 1U]; /* A map between Data length code to the payload size */ -const uint8_t canfd_len_dlc_map[0x10U] = - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U}; +static const uint8_t canfd_len_dlc_map[0x10U] = + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, + 12U, 16U, 20U, 24U, 32U, 48U, 64U}; /* Support functions */ static void canfd_process_rx_message(void); @@ -154,13 +156,13 @@ static int32_t pinmux_config(void) } /** - * @fn void cb_unit_event(uint32_t event) + * @fn static void cb_unit_event(uint32_t event) * @brief CANFD Callback function for events * @note none * @param event: CANFD event * @retval none */ -void cb_unit_event(uint32_t event) +static void cb_unit_event(uint32_t event) { if(event == ARM_CAN_EVENT_UNIT_ACTIVE) { @@ -190,23 +192,25 @@ void cb_unit_event(uint32_t event) } /** - * @fn void cb_object_event(uint32_t obj_idx, uint32_t event) + * @fn static void cb_object_event(uint32_t obj_idx, uint32_t event) * @brief CANFD Callback function for particular object events * @note none * @param obj_idx : Object ID * @param event : CANFD event * @retval none */ -void cb_object_event(uint32_t obj_idx, uint32_t event) +static void cb_object_event(uint32_t obj_idx, uint32_t event) { - if((event & ARM_CAN_EVENT_RECEIVE) || (event & ARM_CAN_EVENT_RECEIVE_OVERRUN)) + if((event & ARM_CAN_EVENT_RECEIVE) || + (event & ARM_CAN_EVENT_RECEIVE_OVERRUN)) { /* Invokes Message Read function if the Receive Object matches */ if(obj_idx == rx_obj_id) { /* Reading arrived CAN Message */ if(CANFD_instance->MessageRead(obj_idx, &rx_msg_header, - rx_data, rx_msg_size) != ARM_DRIVER_OK) + rx_data, + rx_msg_size) != ARM_DRIVER_OK) { rx_msg_error = true; } @@ -228,13 +232,13 @@ void cb_object_event(uint32_t obj_idx, uint32_t event) } /** - * @fn void canfd_demo_task(ULONG thread_input) + * @fn static void canfd_demo_task(ULONG thread_input) * @brief CANFD Demo function * @note none * @param thread_input : Input for thread * @retval none */ -void canfd_demo_task(ULONG thread_input) +static void canfd_demo_task(ULONG thread_input) { CANFD_FRAME msg_type = CANFD_FRAME_STD_ID_CLASSIC_DATA; int32_t ret_val = ARM_DRIVER_OK; @@ -246,6 +250,8 @@ void canfd_demo_task(ULONG thread_input) uint32_t error_code = 0U; uint32_t service_error_code = 0U; + ARG_UNUSED(thread_input); + /* Initialize the SE services */ se_services_port_init(); @@ -406,8 +412,10 @@ void canfd_demo_task(ULONG thread_input) { /* wait for Tx Success/Error callback. */ event_ret = tx_event_flags_get(&event_flags_canfd, - CANFD_ALL_NOTIFICATIONS, TX_OR_CLEAR, - &task_notified_value, TX_WAIT_FOREVER); + CANFD_ALL_NOTIFICATIONS, + TX_OR_CLEAR, + &task_notified_value, + TX_WAIT_FOREVER); if(event_ret != TX_SUCCESS) { printf("Error: CANFD event flags\n"); @@ -536,8 +544,8 @@ void tx_application_define(void *first_unused_memory) { UINT status; - /* Put system definition stuff in here, e.g. thread creates and other assorted - create information. */ + /* Put system definition stuff in here, e.g. thread creates and + other assorted create information. */ /* Create the event flags group used by CANFD thread */ status = tx_event_flags_create(&event_flags_canfd, "CANFD Events"); @@ -549,8 +557,8 @@ void tx_application_define(void *first_unused_memory) /* Create the main thread. */ status = tx_thread_create(&canfd_thread, "CANFD_LBEM", canfd_demo_task, - 0U, first_unused_memory, THREAD_STACK_SIZE, 1U, 1U, - TX_NO_TIME_SLICE, TX_AUTO_START); + 0U, first_unused_memory, THREAD_STACK_SIZE, + 1U, 1U, TX_NO_TIME_SLICE, TX_AUTO_START); if(status != TX_SUCCESS) { printf("Unable to Create Normal Mode Task\n"); @@ -559,13 +567,13 @@ void tx_application_define(void *first_unused_memory) } /** - * @fn void canfd_check_error(void) + * @fn static void canfd_check_error(void) * @brief Checks for the errors in CANFD * @note none * @param none * @retval none */ -void canfd_check_error(void) +static void canfd_check_error(void) { ARM_CAN_STATUS cur_sts; @@ -590,13 +598,13 @@ void canfd_check_error(void) } /** - * @fn void canfd_process_rx_message(void) + * @fn static void canfd_process_rx_message(void) * @brief Processes the received messages * @note none * @param none * @retval none */ -void canfd_process_rx_message(void) +static void canfd_process_rx_message(void) { uint8_t iter = 0U; @@ -630,7 +638,8 @@ void canfd_process_rx_message(void) } printf("Id:%lu, Len:%d:\r\n Data:", - (rx_msg_header.id & (~ARM_CAN_ID_IDE_Msk)), rx_msg_size); + (rx_msg_header.id & (~ARM_CAN_ID_IDE_Msk)), + rx_msg_size); for(iter = 0; iter < rx_msg_size; iter++) { printf("%c", rx_data[iter]); @@ -653,19 +662,17 @@ void canfd_process_rx_message(void) } /** - * @fn bool canfd_transmit_message(CANFD_FRAME msg_type) + * @fn static bool canfd_transmit_message(CANFD_FRAME msg_type) * @brief Prepares and sends message * @note none * @param msg_type : Type of msg to send * @retval none */ -bool canfd_transmit_message(const CANFD_FRAME msg_type) +static bool canfd_transmit_message(const CANFD_FRAME msg_type) { - uint32_t status = ARM_DRIVER_OK; - uint8_t iter; + int32_t status = ARM_DRIVER_OK; + uint8_t iter = 0U; - /* If the previous message is successfully sent, - * then prepare and transmit next message */ switch(msg_type) { case CANFD_FRAME_STD_ID_CLASSIC_DATA: diff --git a/THREADX/samples/CMP_testapp.c b/THREADX/samples/CMP_testapp.c index f223ce1..788e7ae 100644 --- a/THREADX/samples/CMP_testapp.c +++ b/THREADX/samples/CMP_testapp.c @@ -21,12 +21,16 @@ * - Input B is set by RTE_CMP0_SEL_NEGATIVE * - Input B is set to RTE_CMP_NEGATIVE_DAC6(which provide 0.9v) * Hardware setup (1 wires needed): - * - Use a wire to connect P0_0 to P12_3(J14 it will be labeled) - * - This test expects the LED Blinky application is running and - * the P12_3 should be toggling every 1 second - * - When the comparator input changes from HIGH to LOW or from LOW - * to HIGH, interrupt will be generated - * - Check CMP0 output in the pin P14_7 using saleae logic analyzer + * - Connect P0_0(+ve pin) to P12_3(GPIO output) and DAC6 is set as negative + * pin,check CMP0 output in the pin P14_7 using saleae logic analyzer. + * - If +ve input is greater than -ve input, interrupt will be generated, + * and the output will be high. + * - If -ve input is greater than +ve input, interrupt will be generated, + * and the output will be low. + * For window control feature: + * - As glb_events/utimer events are active for few clocks, set prescalar + * value to 0. These interrupt will occur continuously because Utimer + * is running continuously. ******************************************************************************/ /* System Includes */ @@ -35,6 +39,7 @@ #include "tx_api.h" #include "system_utils.h" #include "pinconf.h" +#include "Driver_UTIMER.h" /* include for Comparator Driver */ #include "Driver_CMP.h" @@ -47,8 +52,12 @@ #define GPIO12_PORT 12 /* Use LED0_R,LED0_B GPIO port */ #define LED0_R PIN_3 /* LED0_R gpio pin */ -#define NUM_TAPS 5 /* Number of filter taps */ -#define SAMPLING_RATE 8 /* clock rate for filtering */ +/* To read the HSCMP0 output status set CMP_OUTPIN as 7, for HSCMP1 set CMP_OUTPIN as 6, + * for set CMP_OUTPIN as HSCMP2 5, and for HSCMP3 set CMP_OUTPIN as 4 */ +#define CMP14_PORT 14 +#define CMP_OUTPIN 7 + +#define NUM_TAPS 5 /* Number of filter taps */ #define LPCMP 0 #define HSCMP 1 @@ -57,12 +66,28 @@ /* To configure for LPCMP, use CMP_INSTANCE LPCMP */ #define CMP_INSTANCE HSCMP +/* To enable comparator window control, change the macro value from 0 to 1 + * The glb_events/utimer events define the window where to look at the cmp_input. + * As GLB_events/Utimer_events are active for few clocks, there is no reason to set + * prescaler value, so set Prescaler value to 0 when using window control. + * As Utimer is running continuously, the HSCMP interrupts will occur continuously. */ +#define CMP_WINDOW_CONTROL 0 + +#if CMP_WINDOW_CONTROL +#define SAMPLING_RATE 0 /* Set the prescaler values as 0 for windowing function */ +#else +#define SAMPLING_RATE 8 /* Set the prescaler values from 0 to 31 */ +#endif + #define ERROR -1 #define SUCCESS 0 extern ARM_DRIVER_GPIO ARM_Driver_GPIO_(GPIO12_PORT); ARM_DRIVER_GPIO *ledDrv = &ARM_Driver_GPIO_(GPIO12_PORT); +extern ARM_DRIVER_GPIO ARM_Driver_GPIO_(CMP14_PORT); +ARM_DRIVER_GPIO *CMPout = &ARM_Driver_GPIO_(CMP14_PORT); + #if(CMP_INSTANCE == LPCMP) #if !defined(M55_HE) #error "This Demo application works only on RTSS_HE" @@ -75,16 +100,156 @@ static ARM_DRIVER_CMP *CMPdrv = &Driver_CMP0; #endif volatile uint32_t call_back_counter = 0; +uint32_t value =0; /* Define the ThreadX object control blocks... */ #define DEMO_STACK_SIZE 1024 -#define DEMO_BYTE_POOL_SIZE 9120 #define TX_CMP_FILTER_EVENT 0x01 TX_THREAD CMP_thread; -TX_BYTE_POOL byte_pool_0; -UCHAR memory_area[DEMO_BYTE_POOL_SIZE]; -TX_EVENT_FLAGS_GROUP event_flags_CMP; +TX_EVENT_FLAGS_GROUP event_flags; + +/* Use window control(External trigger using UTIMER or QEC) to trigger the comparator comparison */ +#if(CMP_INSTANCE == HSCMP) +#if CMP_WINDOW_CONTROL + +/* UTIMER0 Driver instance */ +extern ARM_DRIVER_UTIMER DRIVER_UTIMER0; +ARM_DRIVER_UTIMER *ptrUTIMER = &DRIVER_UTIMER0; + +#define UTIMER_COMPARE_A_CB_EVENT (1U << 2U) +#define UTIMER_COMPARE_MODE_WAIT_TIME (5U * TX_TIMER_TICKS_PER_SECOND) /* 5 seconds wait time */ +#define TX_UTIMER_START 0X02 + +ULONG events; +TX_THREAD compare_mode_thread; + +/** + * @function void utimer_compare_mode_cb_func(event) + * @brief utimer compare mode callback function + * @note none + * @param event + * @retval none + */ +static void utimer_compare_mode_cb_func(UCHAR event) +{ + if (event == ARM_UTIMER_EVENT_COMPARE_A) { + tx_event_flags_set(&event_flags, UTIMER_COMPARE_A_CB_EVENT, TX_OR); + } +} + +/** + * @function void utimer_compare_mode_app(void) + * @brief utimer compare mode application + * @note none + * @param none + * @retval none + */ +static void utimer_compare_mode_app(ULONG thread_input) +{ + INT ret; + UCHAR channel = 0; + UINT count_array[3]; + + pinconf_set(0, 0, PINMUX_ALTERNATE_FUNCTION_4, 0); + + /* + * utimer channel 0 is configured for utimer compare mode (driver A). + * observe driver A output signal from P1_2. + */ + /* + * System CLOCK frequency (F)= 400Mhz + * + * Time for 1 count T = 1/F = 1/(400*10^6) = 0.0025 * 10^-6 + * + * To Increment or Decrement Timer by 1 count, takes 0.0025 micro sec + * + * So count for 1 sec = 1/(0.0025*(10^-6)) = 400000000 + * DEC = 400000000 + * HEX = 0x17D78400 + * + * So count for 500ms = (500*(10^-3)/(0.0025*(10^-6)) = 200000000 + * DEC = 200000000 + * HEX = 0xBEBC200 + */ + count_array[0] = 0x000000000; /*< initial counter value >*/ + count_array[1] = 0x17D78400; /*< over flow count value > */ + count_array[2] = 0xBEBC200; /*< compare a/b value> */ + + tx_event_flags_get(&event_flags, TX_UTIMER_START, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + ret = ptrUTIMER->Initialize (channel, utimer_compare_mode_cb_func); + if (ret != ARM_DRIVER_OK) { + printf("utimer channel %d failed initialize \n", channel); + return; + } + + ret = ptrUTIMER->PowerControl (channel, ARM_POWER_FULL); + if (ret != ARM_DRIVER_OK) { + printf("utimer channel %d failed power up \n", channel); + goto error_compare_mode_uninstall; + } + + ret = ptrUTIMER->ConfigCounter (channel, ARM_UTIMER_MODE_COMPARING, ARM_UTIMER_COUNTER_UP); + if (ret != ARM_DRIVER_OK) { + printf("utimer channel %d mode configuration failed \n", channel); + goto error_compare_mode_poweroff; + } + + ret = ptrUTIMER->SetCount (channel, ARM_UTIMER_CNTR, count_array[0]); + if (ret != ARM_DRIVER_OK) { + printf("utimer channel %d set count failed \n", channel); + goto error_compare_mode_poweroff; + } + + ret = ptrUTIMER->SetCount (channel, ARM_UTIMER_CNTR_PTR, count_array[1]); + if (ret != ARM_DRIVER_OK) { + printf("utimer channel %d set count failed \n", channel); + goto error_compare_mode_poweroff; + } + + ret = ptrUTIMER->SetCount (channel, ARM_UTIMER_COMPARE_A, count_array[2]); + if (ret != ARM_DRIVER_OK) { + printf("utimer channel %d set count failed \n", channel); + goto error_compare_mode_poweroff; + } + + ret = ptrUTIMER->Start(channel); + if (ret != ARM_DRIVER_OK) { + printf("utimer channel %d failed to start \n", channel); + goto error_compare_mode_poweroff; + } + + ret = tx_event_flags_get(&event_flags, UTIMER_COMPARE_A_CB_EVENT, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + if(ret != TX_SUCCESS) { + printf("ERROR : event not received \n"); + goto error_compare_mode_poweroff; + } + + return; + + ret = ptrUTIMER->Stop (channel, ARM_UTIMER_COUNTER_CLEAR); + if (ret != ARM_DRIVER_OK) { + printf("utimer channel %d failed to stop \n", channel); + } + +error_compare_mode_poweroff: + + ret = ptrUTIMER->PowerControl (channel, ARM_POWER_OFF); + if (ret != ARM_DRIVER_OK) { + printf("utimer channel %d failed power off \n", channel); + } + +error_compare_mode_uninstall: + + ret = ptrUTIMER->Uninitialize (channel); + if(ret != ARM_DRIVER_OK) { + printf("utimer channel %d failed to un-initialize \n", channel); + } +} + +#endif +#endif /** * @fn void cmp_pinmux_config(void) @@ -127,7 +292,7 @@ int32_t cmp_pinmux_config(void) * @param[in] None * return status */ -int32_t led_init(void) +static int32_t led_init(void) { int32_t ret1 = 0; @@ -141,6 +306,12 @@ int32_t led_init(void) return ERROR; } + ret1 = CMPout->Initialize(CMP_OUTPIN, NULL); + if(ret1 != ARM_DRIVER_OK) { + printf("ERROR: Failed to initialize\n"); + return ERROR; + } + /* Enable the power for LED0_R */ ret1 = ledDrv->PowerControl(LED0_R, ARM_POWER_FULL); if(ret1 != ARM_DRIVER_OK) { @@ -148,7 +319,20 @@ int32_t led_init(void) goto error_uninitialize_LED; } + /* Enable the power for LED0_R */ + ret1 = CMPout->PowerControl(CMP_OUTPIN, ARM_POWER_FULL); + if(ret1 != ARM_DRIVER_OK) { + printf("ERROR: Failed to powered full\n"); + goto error_uninitialize_LED; + } + ret1 = ledDrv->SetDirection(LED0_R, GPIO_PIN_DIRECTION_OUTPUT); + if(ret1 != ARM_DRIVER_OK) { + printf("ERROR: Failed to configure\n"); + goto error_power_off_LED; + } + + ret1 = CMPout->SetDirection(CMP_OUTPIN, GPIO_PIN_DIRECTION_OUTPUT); if(ret1 != ARM_DRIVER_OK) { printf("ERROR: Failed to configure\n"); goto error_power_off_LED; @@ -178,6 +362,37 @@ int32_t led_init(void) return ERROR; } +/** + * @fn cmp_get_status(void) + * @brief - Get the Status of CMP output pin. + * @param[in] None + * return status + */ +static int32_t cmp_get_status(void) +{ + int32_t ret = 0; + ret = CMPout->GetValue(CMP_OUTPIN, &value); + if(ret != ARM_DRIVER_OK) { + printf("ERROR: Failed to toggle LEDs\n"); + goto error_power_off_LED; + } + return value; + + error_power_off_LED: + /* Power-off the CMP_OUTPIN */ + ret = CMPout->PowerControl(CMP_OUTPIN, ARM_POWER_OFF); + if(ret != ARM_DRIVER_OK) { + printf("ERROR: Failed to power off \n"); + } + + /* Uninitialize the CMP_OUTPIN */ + ret = CMPout->Uninitialize(CMP_OUTPIN); + if(ret != ARM_DRIVER_OK) { + printf("Failed to Un-initialize \n"); + } + return ERROR; +} + /** * @fn led_toggle(void) * @brief - set LED0_R for toggle @@ -226,7 +441,7 @@ static void CMP_filter_callback(uint32_t event) if(event & ARM_CMP_FILTER_EVENT_OCCURRED) { /* Received Comparator filter event */ - tx_event_flags_set(&event_flags_CMP, TX_CMP_FILTER_EVENT, TX_OR); + tx_event_flags_set(&event_flags, TX_CMP_FILTER_EVENT, TX_OR); } call_back_counter++; } @@ -237,7 +452,7 @@ void CMP_demo_Thread_entry(ULONG thread_input) INT ret = 0; UINT loop_count = 10; ARM_DRIVER_VERSION version; - ARM_COMPARATOR_CAPABILITIES capabilities; + CHAR status = 0; printf("\r\n >>> Comparator demo threadX starting up!!! <<< \r\n"); @@ -272,6 +487,16 @@ void CMP_demo_Thread_entry(ULONG thread_input) } #if(CMP_INSTANCE == HSCMP) + +#if CMP_WINDOW_CONTROL + /* Start CMP using window control */ + ret = CMPdrv->Control(ARM_CMP_WINDOW_CONTROL_ENABLE, ARM_CMP_WINDOW_CONTROL_SRC_0); + if (ret != ARM_DRIVER_OK) { + printf("\r\n Error: CMP External trigger enable failed\n"); + goto error_poweroff; + } +#endif + /* Filter function for analog comparator*/ ret = CMPdrv->Control(ARM_CMP_FILTER_CONTROL, NUM_TAPS); if(ret != ARM_DRIVER_OK){ @@ -294,7 +519,13 @@ void CMP_demo_Thread_entry(ULONG thread_input) goto error_poweroff; } - while(loop_count--) +#if(CMP_INSTANCE == HSCMP) +#if CMP_WINDOW_CONTROL + tx_event_flags_set(&event_flags, TX_UTIMER_START, TX_OR); +#endif +#endif + + while(loop_count --) { /* Toggle the LED0_R */ if(led_toggle()) @@ -304,7 +535,7 @@ void CMP_demo_Thread_entry(ULONG thread_input) } /* wait till the input changes ( isr callback ) */ - ret = tx_event_flags_get(&event_flags_CMP, TX_CMP_FILTER_EVENT, TX_OR_CLEAR, &event, TX_WAIT_FOREVER); + ret = tx_event_flags_get(&event_flags, TX_CMP_FILTER_EVENT, TX_OR_CLEAR, &event, TX_WAIT_FOREVER); if(ret != TX_SUCCESS) { printf("Error: Comparator tx_event_flags_get\n"); goto error_poweroff; @@ -313,9 +544,38 @@ void CMP_demo_Thread_entry(ULONG thread_input) /* Introducing a delay to stabilize input voltage for comparator measurement*/ tx_thread_sleep(1 * TX_TIMER_TICKS_PER_SECOND); - printf("\n >>> Filter event occurred <<< \n"); + /* Check the status of the CMP output pin */ + status = cmp_get_status(); + + /* If user give +ve input voltage more than -ve input voltage, status will be set to 1*/ + if(status == 1) + { + printf("\n CMP positive input voltage is greater than negative input voltage\n"); + } + /* If user give -ve input voltage more than +ve input voltage, status will be set to 0*/ + else if(status == 0) + { + printf("\n CMP negative input voltage is greater than the positive input voltage\n"); + } + else + { + printf("ERROR: Status detection is failed\n"); + goto error_poweroff; + } + } +#if(CMP_INSTANCE == HSCMP) +#if CMP_WINDOW_CONTROL + /* Disable CMP window control */ + ret = CMPdrv->Control(ARM_CMP_WINDOW_CONTROL_DISABLE, ARM_CMP_WINDOW_CONTROL_SRC_0); + if (ret != ARM_DRIVER_OK) { + printf("\r\n Error: CMP External trigger enable failed\n"); + goto error_poweroff; + } +#endif +#endif + /* To Stop the comparator module */ ret = CMPdrv->Stop(); if(ret != ARM_DRIVER_OK){ @@ -361,45 +621,38 @@ int main() /* Define what the initial system looks like. */ void tx_application_define(void *first_unused_memory) { - CHAR *pointer = TX_NULL; INT status; - /* Create a byte memory pool from which to allocate the thread stacks. */ - status = tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_area, DEMO_BYTE_POOL_SIZE); - if(status != TX_SUCCESS) - { - printf("Could not create byte pool\n"); - return; - } - - /* Put system definition stuff in here, e.g. thread creates and other assorted - create information. */ - /* Create the event flags group used by Comparator thread */ - status = tx_event_flags_create(&event_flags_CMP, "event flags CMP"); + status = tx_event_flags_create(&event_flags, "event flags CMP"); if(status != TX_SUCCESS) { printf("Could not create event flags\n"); return; } - /* Allocate the stack for thread 0. */ - status = tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); - if(status != TX_SUCCESS) - { - printf("Could not create byte allocate\n"); - return; - } - /* Create the main thread. */ - status = tx_thread_create(&CMP_thread, "CMP_thread", CMP_demo_Thread_entry, 0, - pointer, DEMO_STACK_SIZE, - 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + status = tx_thread_create(&CMP_thread, "CMP_thread", CMP_demo_Thread_entry, + 0,first_unused_memory, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); if(status != TX_SUCCESS) { printf("Could not create thread\n"); return; } + +#if(CMP_INSTANCE == HSCMP) +#if CMP_WINDOW_CONTROL + /* Create the utimer compare mode thread. */ + status = tx_thread_create(&compare_mode_thread, "UTIMER COMPARE MODE THREAD", utimer_compare_mode_app, + 0,first_unused_memory + DEMO_STACK_SIZE, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + if (status != TX_SUCCESS) { + printf("failed to create utimer compare mode thread\r\n"); + } + +#endif +#endif } /************************ (C) COPYRIGHT ALIF SEMICONDUCTOR *****END OF FILE****/ diff --git a/THREADX/samples/LPPDM_testApp.c b/THREADX/samples/LPPDM_testApp.c index 40daa59..9a15ddd 100644 --- a/THREADX/samples/LPPDM_testApp.c +++ b/THREADX/samples/LPPDM_testApp.c @@ -67,6 +67,18 @@ #define CHANNEL_0 0 #define CHANNEL_1 1 +/* PDM Channel 0 configurations */ +#define CH0_PHASE 0x00000003 +#define CH0_GAIN 0x00000013 +#define CH0_PEAK_DETECT_TH 0x00060002 +#define CH0_PEAK_DETECT_ITV 0x00020027 + +/* PDM Channel 1 configurations */ +#define CH1_PHASE 0x0000001F +#define CH1_GAIN 0x0000000D +#define CH1_PEAK_DETECT_TH 0x00060002 +#define CH1_PEAK_DETECT_ITV 0x0004002D + /* PDM driver instance */ extern ARM_DRIVER_PDM Driver_LPPDM; static ARM_DRIVER_PDM *PDMdrv = &Driver_LPPDM; @@ -146,10 +158,10 @@ void PDM_fifo_callback(uint32_t event) */ void pdm_demo_thread_entry(ULONG thread_input) { - int32_t ret = 0; + INT ret = 0; ULONG actual_events = 0; ARM_DRIVER_VERSION version; - int32_t retval; + INT retval; printf("\r\n >>> PDM demo starting up!!! <<< \r\n"); @@ -158,12 +170,12 @@ void pdm_demo_thread_entry(ULONG thread_input) /* Data line for Channel 0 and 1 (LPPDM_D0_B -> pin P3_5) */ retval = pinconf_set(PORT_3, PIN_5, PINMUX_ALTERNATE_FUNCTION_3, PADCTRL_READ_ENABLE); - if (retval) + if(retval) printf("pinconf_set failed\n"); /* Clock line for Channel 0 and 1 (LPPDM_C0_B -> pin P3_4) */ retval = pinconf_set(PORT_3, PIN_4, PINMUX_ALTERNATE_FUNCTION_3, 0x0); - if (retval) + if(retval) printf("pinconf_set failed\n"); /* Initialize PDM driver */ @@ -181,49 +193,57 @@ void pdm_demo_thread_entry(ULONG thread_input) } /* To select the PDM channel 0 and channel 1 */ - ret = PDMdrv->Control(ARM_PDM_SELECT_CHANNEL, (ARM_PDM_MASK_CHANNEL_0 | ARM_PDM_MASK_CHANNEL_1)); + ret = PDMdrv->Control(ARM_PDM_SELECT_CHANNEL, (ARM_PDM_MASK_CHANNEL_0 | ARM_PDM_MASK_CHANNEL_1), NULL); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM channel select control failed\n"); goto error_poweroff; } /* Select Standard voice PDM mode */ - ret = PDMdrv->Control(ARM_PDM_MODE, ARM_PDM_MODE_STANDARD_VOICE_512_CLK_FRQ); + ret = PDMdrv->Control(ARM_PDM_MODE, ARM_PDM_MODE_STANDARD_VOICE_512_CLK_FRQ, NULL); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM Standard voice control mode failed\n"); goto error_poweroff; } /* Select the DC blocking IIR filter */ - ret = PDMdrv->Control(ARM_PDM_BYPASS_IIR_FILTER, ENABLE); + ret = PDMdrv->Control(ARM_PDM_BYPASS_IIR_FILTER, ENABLE, NULL); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM DC blocking IIR control failed\n"); goto error_poweroff; } - /* Channel 0 configuration values */ - pdm_coef_reg.ch_num = CHANNEL_0; /* Channel 0 */ - memcpy(pdm_coef_reg.ch_fir_coef, ch0_fir, sizeof(pdm_coef_reg.ch_fir_coef)); /* Channel 0 fir coefficient */ - pdm_coef_reg.ch_iir_coef = 0x00000004; /* Channel IIR Filter Coefficient */ - pdm_coef_reg.ch_phase = 0x00000003; /* Channel Phase Control */ - pdm_coef_reg.ch_gain = 0x00000013; /* Channel gain control */ - pdm_coef_reg.ch_peak_detect_th = 0x00060002; /* Channel Peak Detector Threshold */ - pdm_coef_reg.ch_peak_detect_itv = 0x00020027; /* Channel Peak Detector Interval */ + /* Set Channel 0 Phase value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PHASE, CHANNEL_0, CH0_PHASE); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } - ret = PDMdrv->Config(&pdm_coef_reg); + /* Set Channel 0 Gain value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_GAIN, CHANNEL_0, CH0_GAIN); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM Channel_Config failed\n"); goto error_uninitialize; } - /* Channel 1 configuration values */ - pdm_coef_reg.ch_num = CHANNEL_1; /* Channel 1 */ - memcpy(pdm_coef_reg.ch_fir_coef, ch1_fir, sizeof(pdm_coef_reg.ch_fir_coef)); /* Channel 1 fir coefficient*/ + /* Set Channel 0 Peak detect threshold value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PEAK_DETECT_TH, CHANNEL_0, CH0_PEAK_DETECT_TH); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + /* Set Channel 0 Peak detect ITV value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PEAK_DETECT_ITV, CHANNEL_0, CH0_PEAK_DETECT_ITV); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + pdm_coef_reg.ch_num = CHANNEL_0; + memcpy(pdm_coef_reg.ch_fir_coef, ch0_fir, sizeof(pdm_coef_reg.ch_fir_coef)); /* Channel 0 fir coefficient */ pdm_coef_reg.ch_iir_coef = 0x00000004; /* Channel IIR Filter Coefficient */ - pdm_coef_reg.ch_phase = 0x0000001F; /* Channel Phase Control */ - pdm_coef_reg.ch_gain = 0x0000000D; /* Channel gain control */ - pdm_coef_reg.ch_peak_detect_th = 0x00060002; /* Channel Peak Detector Threshold */ - pdm_coef_reg.ch_peak_detect_itv = 0x0004002D; /* Channel Peak Detector Interval */ ret = PDMdrv->Config(&pdm_coef_reg); if(ret != ARM_DRIVER_OK){ @@ -231,6 +251,39 @@ void pdm_demo_thread_entry(ULONG thread_input) goto error_uninitialize; } + /* Set Channel 1 Phase value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PHASE, CHANNEL_1, CH1_PHASE); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + /* Set Channel 1 Gain value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_GAIN, CHANNEL_1, CH1_GAIN); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + /* Set Channel 1 Peak detect threshold value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PEAK_DETECT_TH, CHANNEL_1, CH1_PEAK_DETECT_TH); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + /* Set Channel 1 Peak detect ITV value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PEAK_DETECT_ITV, CHANNEL_1, CH1_PEAK_DETECT_ITV); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + /* Channel 1 configuration values */ + pdm_coef_reg.ch_num = CHANNEL_1; /* Channel 1 */ + memcpy(pdm_coef_reg.ch_fir_coef, ch1_fir, sizeof(pdm_coef_reg.ch_fir_coef)); /* Channel 1 fir coefficient*/ + pdm_coef_reg.ch_iir_coef = 0x00000004; /* Channel IIR Filter Coefficient */ + ret = PDMdrv->Config(&pdm_coef_reg); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM Channel_Config failed\n"); diff --git a/THREADX/samples/MIPI_Interface_Video_testApp.c b/THREADX/samples/MIPI_Interface_Video_testApp.c index 7949e0f..98b5b2d 100644 --- a/THREADX/samples/MIPI_Interface_Video_testApp.c +++ b/THREADX/samples/MIPI_Interface_Video_testApp.c @@ -7,47 +7,46 @@ * contact@alifsemi.com, or visit: https://alifsemi.com/license * */ - /**************************************************************************//** * @file MIPI_interface_Video_testApp.c - * @author Prasanna Ravi - * @email prasanna.ravi@alifsemi.com + * @author Prasanna Ravi and Chandra Bhushan Singh + * @email prasanna.ravi@alifsemi.com and chandrabhushan.singh@alifsemi.com * @version V1.0.0 - * @date 18-August-2022 + * @date 14-Dec-2023 * @brief TestApp to verify ARX3A0 Camera Sensor and ILI9806E LCD Panel * with Azure RTOS ThreadX as an Operating System. * @bug None. * @Note None. ******************************************************************************/ - /* System Includes */ #include #include "tx_api.h" /* Project Includes */ + /* Camera Controller Driver */ -#include "Driver_Camera_Controller.h" +#include "Driver_CPI.h" + #include "RTE_Components.h" -#if defined(RTE_Compiler_IO_STDOUT) -#include "retarget_stdout.h" +#if defined(RTE_Compiler_IO_STDOUT) +#include "retarget_stdout.h" #endif /* RTE_Compiler_IO_STDOUT */ - -/* Camera Resolution */ -#include "Camera_Common.h" - /* PINMUX Driver */ -#include "Driver_PINMUX_AND_PINPAD.h" +#include "pinconf.h" /* CDC200 Driver*/ #include "Driver_CDC200.h" +/* SE Services */ +#include "se_services_port.h" + /* Device Header files*/ #include CMSIS_device_header /* Camera Driver instance 0 */ -extern ARM_DRIVER_CAMERA_CONTROLLER Driver_CAMERA0; -static ARM_DRIVER_CAMERA_CONTROLLER *CAMERAdrv = &Driver_CAMERA0; +extern ARM_DRIVER_CPI Driver_CPI; +static ARM_DRIVER_CPI *CAMERAdrv = &Driver_CPI; /*CDC200 Driver instance*/ extern ARM_DRIVER_CDC200 Driver_CDC200; @@ -59,10 +58,10 @@ void video_demo_thread_entry(ULONG thread_input); #define DEMO_STACK_SIZE 1024 #define DEMO_BYTE_POOL_SIZE 9120 -TX_THREAD Video_thread; -TX_BYTE_POOL byte_pool_0; -UCHAR memory_area[DEMO_BYTE_POOL_SIZE]; -TX_EVENT_FLAGS_GROUP event_flags; +TX_THREAD Video_thread; +TX_BYTE_POOL byte_pool_0; +UCHAR memory_area[DEMO_BYTE_POOL_SIZE]; +TX_EVENT_FLAGS_GROUP event_flags; /* @Note: ARX3A0 Camera Sensor configurations * are directly borrowed from ARX3A0 Camera Sensor drivers, @@ -70,22 +69,13 @@ TX_EVENT_FLAGS_GROUP event_flags; * * Selected ARX3A0 Camera Sensor configurations: * - Interface : MIPI CSI2 - * - Resolution : 560X560 and 480x480 + * - Resolution : 560X560 * - Output Format : RAW Bayer10 */ /* ARX3A0 Camera Sensor Resolution. */ -#define ARX3A0_CAMERA_RESOLUTION_560x560 0 -#define ARX3A0_CAMERA_RESOLUTION_480x480 1 -#define ARX3A0_CAMERA_RESOLUTION ARX3A0_CAMERA_RESOLUTION_480x480 - -#if (ARX3A0_CAMERA_RESOLUTION == ARX3A0_CAMERA_RESOLUTION_560x560) #define CAM_FRAME_WIDTH (560) #define CAM_FRAME_HEIGHT (560) -#elif (ARX3A0_CAMERA_RESOLUTION == ARX3A0_CAMERA_RESOLUTION_480x480) -#define CAM_FRAME_WIDTH (480) -#define CAM_FRAME_HEIGHT (480) -#endif /* Allocate Camera frame buffer memory using memory pool section in * Linker script (sct scatter) file. @@ -125,7 +115,7 @@ uint8_t cam_framebuffer_pool[CAMERA_FRAMEBUFFER_POOL_SIZE] \ #define RGB_BYTES_PER_PIXEL 3 /* Enable image Cropping and interpolate. */ -#define IMAGE_CROP_AND_INTERPOLATE_EN 0 +#define IMAGE_CROP_AND_INTERPOLATE_EN 1 #if IMAGE_CROP_AND_INTERPOLATE_EN @@ -155,7 +145,6 @@ uint8_t lcd_framebuffer_pool[LCD_FRAMEBUFFER_POOL_SIZE] \ * we have Crop and interpolate the captured image * to 480x480. */ - #if (ILI9806E_Panel_RESOLUTION == ILI9806E_Panel_RESOLUTION_480x800) #define CRP_FRAME_WIDTH (480) #define CRP_FRAME_HEIGHT (480) @@ -205,17 +194,8 @@ uint8_t crop_and_interpolate_buffer_pool[CRP_FRAMEBUFFER_POOL_SIZE] \ * "Open-Source" code for Bayer to RGB Conversion * which uses DC1394 library. */ - -#define LCD_BUF_BASE SRAM0_BASE -#define LCD_BUF_SIZE ( CRP_FRAMEBUFFER_POOL_SIZE + LCD_FRAMEBUFFER_POOL_SIZE ) - #endif -/* Enable image conversion Bayer to RGB. */ -#define IMAGE_CONVERSION_BAYER_TO_RGB_EN 1 - -/* Check if image conversion Bayer to RGB is Enabled? */ -#if IMAGE_CONVERSION_BAYER_TO_RGB_EN /* @Note: Bayer to RGB configurations * are directly borrowed from "Open-Source" code for * Bayer to RGB Conversion, for detail refer bayer2rgb.c. @@ -226,6 +206,7 @@ uint8_t crop_and_interpolate_buffer_pool[CRP_FRAMEBUFFER_POOL_SIZE] \ */ #define TIFF_HDR_NUM_ENTRY 8 #define TIFF_HDR_SIZE 10+TIFF_HDR_NUM_ENTRY*12 + /* bpp bit per pixel * Valid parameters are: * - 8-bit @@ -245,31 +226,31 @@ uint8_t crop_and_interpolate_buffer_pool[CRP_FRAMEBUFFER_POOL_SIZE] \ #define BAYER_TO_RGB_BUFFER_POOL_SIZE \ ( (LCD_FRAME_WIDTH) * (LCD_FRAME_HEIGHT) * (BITS_PER_PIXEL / 8) * RGB_BYTES_PER_PIXEL + TIFF_HDR_SIZE ) #endif + /* pool area for Camera frame buffer for Bayer to RGB conversion. * Allocated in the "camera_frame_bayer_to_rgb_buf" section. */ uint8_t bayer_to_rgb_buffer_pool[BAYER_TO_RGB_BUFFER_POOL_SIZE] \ __attribute__((section("camera_frame_bayer_to_rgb_buf"))); -#define CAM_BUF_BASE SRAM1_BASE -#define CAM_BUF_SIZE ( CAMERA_FRAMEBUFFER_POOL_SIZE + BAYER_TO_RGB_BUFFER_POOL_SIZE ) - /* Optional: * Camera Image Conversions */ -typedef enum { +typedef enum +{ BAYER_TO_RGB_CONVERSION = (1 << 0), }IMAGE_CONVERSION; -#endif /* end of IMAGE_CONVERSION_BAYER_TO_RGB_EN */ - /* Camera callback events */ -typedef enum { +typedef enum +{ CAM_CB_EVENT_ERROR = (1 << 0), DISP_CB_EVENT_ERROR = (1 << 1), CAM_VSYNC_CB_EVENT = (1 << 2) }CB_EVENTS; +volatile uint32_t softreset_interval_counter = 0; + /** \fn void Camera_callback(uint32_t event) \brief Camera isr callback @@ -278,25 +259,32 @@ typedef enum { */ void Camera_callback(uint32_t event) { - if(event & ARM_CAMERA_CONTROLLER_EVENT_CAMERA_FRAME_VSYNC_DETECTED) + if(event & ARM_CPI_EVENT_CAMERA_FRAME_VSYNC_DETECTED) { /* Transfer Success: Frame VSYNC detected, Wake-up Thread. */ tx_event_flags_set(&event_flags, CAM_VSYNC_CB_EVENT, TX_OR); + + if(softreset_interval_counter % 2) + { + CAMERAdrv->Control(CPI_SOFTRESET, 0); + } + + softreset_interval_counter++; } - if(event & ARM_CAMERA_CONTROLLER_EVENT_ERR_CAMERA_FIFO_OVERRUN) + if(event & ARM_CPI_EVENT_ERR_CAMERA_INPUT_FIFO_OVERRUN) { - /* Transfer Error: Received FIFO over-run, Wake-up Thread. */ + /* Transfer Error: Received input FIFO over-run, Wake-up Thread. */ tx_event_flags_set(&event_flags, CAM_CB_EVENT_ERROR, TX_OR); } - if(event & ARM_CAMERA_CONTROLLER_EVENT_ERR_CAMERA_FIFO_UNDERRUN) + if(event & ARM_CPI_EVENT_ERR_CAMERA_OUTPUT_FIFO_OVERRUN) { - /* Transfer Error: Received FIFO under-run, Wake-up Thread. */ + /* Transfer Error: Received output FIFO over-run, Wake-up Thread. */ tx_event_flags_set(&event_flags, CAM_CB_EVENT_ERROR, TX_OR); } - if(event & ARM_CAMERA_CONTROLLER_EVENT_MIPI_CSI2_ERROR) + if(event & ARM_CPI_EVENT_MIPI_CSI2_ERROR) { /* Transfer Error: Received MIPI CSI2 error, Wake-up Thread. */ tx_event_flags_set(&event_flags, CAM_CB_EVENT_ERROR, TX_OR); @@ -321,8 +309,8 @@ void Display_callback(uint32_t event) /** \fn int i3c_pinmux(void) \brief i3c hardware pin initialization: - - PIN-MUX configuration - - PIN-PAD configuration + - PIN-MUX configuration + - PIN-PAD configuration \param[in] none \return 0:success; -1:failure */ @@ -330,47 +318,30 @@ int i3c_pinmux(void) { int ret; - /* Configure GPIO Pin : P3_8 as I3C_SDA_B */ - ret = PINMUX_Config(PORT_NUMBER_3, PIN_NUMBER_8, PINMUX_ALTERNATE_FUNCTION_3); - if(ret != ARM_DRIVER_OK) - { - printf("\r\n Error: i3c PINMUX failed.\r\n"); - return -1; - } + /* Configure GPIO Pin : P7_2 as i2c_sda_c + * Pad function: PADCTRL_READ_ENABLE | + * PADCTRL_DRIVER_DISABLED_PULL_UP + */ + ret = pinconf_set(PORT_7, PIN_2, PINMUX_ALTERNATE_FUNCTION_5, PADCTRL_READ_ENABLE | + PADCTRL_DRIVER_DISABLED_PULL_UP); - /* Configure GPIO Pin : P3_9 as I3C_SCL_B */ - ret = PINMUX_Config(PORT_NUMBER_3, PIN_NUMBER_9, PINMUX_ALTERNATE_FUNCTION_4); if(ret != ARM_DRIVER_OK) { - printf("\r\n Error: i3c PINMUX failed.\r\n"); + printf("\r\n Error: i2c PINMUX and PINPAD failed.\r\n"); return -1; } - /* Pin-Pad P3_8 as I3C_SDA_B - * Pad function: PAD_FUNCTION_READ_ENABLE | - * PAD_FUNCTION_DRIVER_DISABLE_STATE_WITH_PULL_UP | - * PAD_FUNCTION_DRIVER_OPEN_DRAIN - */ - ret = PINPAD_Config(PORT_NUMBER_3, PIN_NUMBER_8, PAD_FUNCTION_READ_ENABLE | - PAD_FUNCTION_DRIVER_DISABLE_STATE_WITH_PULL_UP | - PAD_FUNCTION_DRIVER_OPEN_DRAIN); - if(ret != ARM_DRIVER_OK) - { - printf("\r\n Error: i3c PINPAD failed.\r\n"); - return -1; - } + /* Configure GPIO Pin : P7_3 as i2c_scl_c + * Pad function: PADCTRL_READ_ENABLE | + * PADCTRL_DRIVER_DISABLED_PULL_UP - /* Pin-Pad P3_9 as I3C_SCL_B - * Pad function: PAD_FUNCTION_READ_ENABLE | - * PAD_FUNCTION_DRIVER_DISABLE_STATE_WITH_PULL_UP | - * PAD_FUNCTION_DRIVER_OPEN_DRAIN */ - ret = PINPAD_Config(PORT_NUMBER_3, PIN_NUMBER_9,PAD_FUNCTION_READ_ENABLE | - PAD_FUNCTION_DRIVER_DISABLE_STATE_WITH_PULL_UP | - PAD_FUNCTION_DRIVER_OPEN_DRAIN); + ret = pinconf_set(PORT_7, PIN_3, PINMUX_ALTERNATE_FUNCTION_5, PADCTRL_READ_ENABLE | + PADCTRL_DRIVER_DISABLED_PULL_UP); + if(ret != ARM_DRIVER_OK) { - printf("\r\n Error: i3c PINPAD failed.\r\n"); + printf("\r\n Error: i2c PINMUX and PINPAD failed.\r\n"); return -1; } @@ -380,7 +351,7 @@ int i3c_pinmux(void) /** \fn int camera_pinmux(void) \brief Camera hardware pin initialization: - - PIN-MUX configuration + - PIN-MUX configuration \param[in] none \return 0:success; -1:failure */ @@ -388,113 +359,24 @@ int camera_pinmux() { int ret; - /* @Note: Below GPIO pins are configured for Camera. - * - * For ASIC A1 CPU Board - * - P2_7 as CAM_XVCLK_B - */ -#define ASIC_A1_CPU_BOARD_ENABLE 1 /* Enable ASIC A1 CPU Board */ - -#if ASIC_A1_CPU_BOARD_ENABLE - /* Configure GPIO Pin : P2_7 as CAM_XVCLK_B */ - ret = PINMUX_Config(PORT_NUMBER_2, PIN_NUMBER_7, PINMUX_ALTERNATE_FUNCTION_6); - + /* Configure GPIO Pin : P0_3 as CAM_XVCLK_A */ + ret = pinconf_set(PORT_0, PIN_3, PINMUX_ALTERNATE_FUNCTION_6, 0); if(ret != ARM_DRIVER_OK) { printf("\r\n Error: Camera Pin-Mux failed.\r\n"); return -1; } -#endif return 0; } -/** - \fn static void MPU_Load_Regions(void) - \brief Load the MPU regions from the given table - \note This function loads the region and also sets the - attrbutes for the regions. - \param[in] None - \return None - */ -static void MPU_Load_Regions(void) -{ - static const ARM_MPU_Region_t mpu_table[] __STARTUP_RO_DATA_ATTRIBUTE = { -#if IMAGE_CROP_AND_INTERPOLATE_EN - { - /* LCD Buffer Region making it as Non-sharable, read/write, non-privileged, non-executable */ - .RBAR = ARM_MPU_RBAR(LCD_BUF_BASE, ARM_MPU_SH_NON, 0UL, 1UL, 0UL), - .RLAR = ARM_MPU_RLAR((LCD_BUF_BASE + LCD_BUF_SIZE), 1UL) - }, -#endif - { - /* Camera Buffer Region making it as Non-sharable, read/write, non-privileged, non-executable */ - .RBAR = ARM_MPU_RBAR(CAM_BUF_BASE, ARM_MPU_SH_NON, 0UL, 1UL, 0UL), - .RLAR = ARM_MPU_RLAR((CAM_BUF_BASE + CAM_BUF_SIZE), 1UL) - }, - { - /* Low Power Peripheral Regions */ - .RBAR = ARM_MPU_RBAR(0x70000000UL, ARM_MPU_SH_NON, 0UL, 1UL, 1UL), - .RLAR = ARM_MPU_RLAR(0x72FFFFFFUL, 0UL) - }, - }; - - /* Define the possible Attribute regions */ - ARM_MPU_SetMemAttr(0UL, ARM_MPU_ATTR_DEVICE); /* Attr0, Device Memory */ - /* Attr1, Normal Memory, Cached, Write-through, Read Allocation*/ - ARM_MPU_SetMemAttr(1UL, ARM_MPU_ATTR( - ARM_MPU_ATTR_MEMORY_(0,0,1,0), - ARM_MPU_ATTR_MEMORY_(0,0,1,0))); - - /* Load the regions from the table */ - ARM_MPU_Load(0U, &mpu_table[0], sizeof(mpu_table)/sizeof(ARM_MPU_Region_t));; -} - -/** - \fn void MPU_Clear_All_Regions(void) - \brief Clear all the MPU registers - \note This function disables the MPU and clear - all the existing regions. - \param[in] None - \return None - */ -static void MPU_Clear_All_Regions(void) -{ - MPU_Type* mpu = MPU; - /* Retrieve the number of regions */ - uint32_t num_regions = (mpu->TYPE >> 8); - uint32_t cnt; - - ARM_MPU_Disable(); - - for(cnt = 0U; cnt < num_regions; cnt++) - ARM_MPU_ClrRegion(cnt); -} - -/** - \fn void MPU_Setup(void) - \brief Configure the MPU. - \note This function disables the MPU and loads the regions - from the table. Once it is loaded, MPU is enabled. - \param[in] None - \return None - */ -static void MPU_Setup(void) -{ -#define MPU_CONTROL (MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk) - - MPU_Clear_All_Regions(); - MPU_Load_Regions(); - ARM_MPU_Enable(MPU_CONTROL); -} - /** \fn int hardware_init(void) \brief - i3c hardware pin initialization: - - PIN-MUX configuration - - PIN-PAD configuration - - Camera hardware pin initialization: - - PIN-MUX configuration + - PIN-MUX configuration + - PIN-PAD configuration + - Camera hardware pin initialization: + - PIN-MUX configuration \param[in] none \return 0:success; -1:failure */ @@ -524,28 +406,26 @@ int hardware_init(void) return 0; } -/* Check if image conversion Bayer to RGB is Enabled? */ -#if IMAGE_CONVERSION_BAYER_TO_RGB_EN /** - \fn int camera_image_conversion(IMAGE_CONVERSION image_conversion, - uint8_t *src, - uint8_t *dest, - uint32_t frame_width, - uint32_t frame_height) + \fn int camera_image_conversion(IMAGE_CONVERSION image_conversion, + uint8_t *src, uint8_t *dest, + uint32_t frame_width, + uint32_t rame_height) + \brief Convert image data from one format to any other image format. - - Supported conversions - - Bayer(RAW) to RGB Conversion - - User can use below provided - "Open-Source" Bayer to RGB Conversion code - which uses DC1394 library. - - This code will, - - Add header for tiff image format - - Convert RAW Bayer to RGB depending on - - bpp bit per pixel 8/16 bit - - DC1394 Color Filter - - DC1394 Bayer interpolation methods - - Output image size will be - - width x height x (bpp / 8) x 3 + tiff header(106 Bytes) + - Supported conversions + - Bayer(RAW) to RGB Conversion + - User can use below provided + "Open-Source" Bayer to RGB Conversion code + which uses DC1394 library. + - This code will, + - Add header for tiff image format + - Convert RAW Bayer to RGB depending on + - bpp bit per pixel 8/16 bit + - DC1394 Color Filter + - DC1394 Bayer interpolation methods + - Output image size will be + - width x height x (bpp / 8) x 3 + tiff header(106 Bytes) \param[in] image_conversion : image conversion methods \ref IMAGE_CONVERSION \param[in] src : Source address, Pointer to already available image data Address @@ -553,27 +433,25 @@ int hardware_init(void) where converted image data will be stored. \param[in] frame_width : image frame width \param[in] frame_height : image frame height - \return success : 0 + \return success : 0 \return failure : -1 */ int camera_image_conversion(IMAGE_CONVERSION image_conversion, - uint8_t *src, - uint8_t *dest, - uint32_t frame_width, - uint32_t frame_height) + uint8_t *src, uint8_t *dest, + uint32_t frame_width, + uint32_t frame_height) + { /* Bayer to RGB Conversion. */ - extern int32_t bayer_to_RGB(uint8_t *src, uint8_t *dest, \ - uint32_t width, uint32_t height); + extern int32_t bayer_to_RGB(uint8_t *src, uint8_t *dest, + uint32_t width, uint32_t height); int ret = 0; switch(image_conversion) { case BAYER_TO_RGB_CONVERSION: - printf("\r\n Start Bayer to RGB Conversion: \r\n"); - printf("\t Frame Buffer Addr: 0x%X \r\n \t Bayer_to_RGB Addr: 0x%X\n", \ - (uint32_t) src, (uint32_t) dest); + { ret = bayer_to_RGB(src, dest, frame_width, frame_height); if(ret != 0) { @@ -581,35 +459,37 @@ int camera_image_conversion(IMAGE_CONVERSION image_conversion, return -1; } break; + } default: + { return -1; + } } return 0; } -#endif /* end of IMAGE_CONVERSION_BAYER_TO_RGB_EN */ + /** \fn void video_demo_thread_entry(ULONG thread_input) \brief TestApp to verify ARX3A0 Camera Sensor and ILI9806E LCD Panel with Azure RTOS ThreadX as an Operating System. - - This demo thread does: - - initialize i3c and Camera hardware pins - - initialize CDC200 driver. - - initialize Camera driver with Camera Resolution. - - captured data will display on LCD Panel. - - convert captured image format - into RGB888 image format - - for ARX3A0 Camera sensor, - it gives image in frame resolution560x560 - - for ILI9806E LCD Panel, - it supports resolution 480x800 - - in-order to display the camera image on LCD panel, - we are cropping and interpolate the captured image - to 480x480. - - Stream captured image on LCD Panel + This demo thread does: + - initialize i3c and Camera hardware pins + - initialize CDC200 driver. + - initialize Camera driver with Camera Resolution. + - captured data will display on LCD Panel. + - convert captured image format + into RGB888 image format + - for ARX3A0 Camera sensor, + it gives image in frame resolution560x560 + - for ILI9806E LCD Panel, + it supports resolution 480x800 + - in-order to display the camera image on LCD panel, + we are cropping and interpolate the captured image + to 480x480. + - Stream captured image on LCD Panel \param[in] thread_input : thread input \return none */ @@ -619,14 +499,16 @@ void video_demo_thread_entry(ULONG thread_input) ULONG actual_events = 0; ULONG row = 0, col = 0, index = 0, row_location = 0; ULONG wait_timer_ticks = TX_TIMER_TICKS_PER_SECOND; + UINT service_error_code; + UINT error_code; + + run_profile_t runp = {0}; - ARM_CAMERA_RESOLUTION camera_resolution = 0; ARM_DRIVER_VERSION version; printf("\r\n >>> ARX3A0 Camera Sensor and ILI9806E LCD Panel demo " "with Azure RTOS ThreadX is starting up!!! <<< \r\n"); - /* Allocated memory address for * - Camera frame buffer and * - Camera frame buffer for Bayer to RGB Conversion. @@ -657,22 +539,55 @@ void video_demo_thread_entry(ULONG thread_input) return; } - version = CAMERAdrv->GetVersion(); - printf("\r\n Camera driver version api:0x%X driver:0x%X \r\n",version.api, version.drv); + /* Initialize the SE services */ + se_services_port_init(); - version = CDCdrv->GetVersion(); - printf("\r\n CDC driver version api:0x%X driver:0x%X \r\n",version.api, version.drv); + /* Enable MIPI Clocks */ + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, CLKEN_CLK_100M, + true, &service_error_code); + if(error_code != SERVICES_REQ_SUCCESS) + { + printf("SE: MIPI 100MHz clock enable = %d\n", error_code); + return; + } + + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, CLKEN_HFOSC, + true, &service_error_code); + if(error_code != SERVICES_REQ_SUCCESS) + { + printf("SE: MIPI 38.4Mhz(HFOSC) clock enable = %d\n", error_code); + goto error_disable_100mhz_clk; + } - /* Initialize CAMERA driver with Camera Resolution */ - if (ARX3A0_CAMERA_RESOLUTION == ARX3A0_CAMERA_RESOLUTION_560x560) + /* Get the current run configuration from SE */ + error_code = SERVICES_get_run_cfg(se_services_s_handle, + &runp, + &service_error_code); + if(error_code) { - camera_resolution = CAMERA_RESOLUTION_560x560; + printf("\r\nSE: get_run_cfg error = %d\n", error_code); + goto error_disable_hfosc_clk; } - else if (ARX3A0_CAMERA_RESOLUTION == ARX3A0_CAMERA_RESOLUTION_480x480) + + runp.memory_blocks = MRAM_MASK | SRAM0_MASK; + runp.phy_pwr_gating = MIPI_PLL_DPHY_MASK | MIPI_TX_DPHY_MASK | MIPI_RX_DPHY_MASK | LDO_PHY_MASK; + + /* Set the new run configuration */ + error_code = SERVICES_set_run_cfg(se_services_s_handle, + &runp, + &service_error_code); + if(error_code) { - camera_resolution = CAMERA_RESOLUTION_480x480; + printf("\r\nSE: set_run_cfg error = %d\n", error_code); + goto error_disable_hfosc_clk; } + version = CAMERAdrv->GetVersion(); + printf("\r\n Camera driver version api:0x%X driver:0x%X \r\n",version.api, version.drv); + + version = CDCdrv->GetVersion(); + printf("\r\n CDC driver version api:0x%X driver:0x%X \r\n",version.api, version.drv); + /* Initialize Display Driver CDC200*/ ret = CDCdrv->Initialize(Display_callback); if(ret != 0) @@ -682,7 +597,7 @@ void video_demo_thread_entry(ULONG thread_input) } /* Initialize Camera Driver*/ - ret = CAMERAdrv->Initialize(camera_resolution, Camera_callback); + ret = CAMERAdrv->Initialize(Camera_callback); if(ret != ARM_DRIVER_OK) { printf("\r\n Error: CAMERA Initialize failed.\r\n"); @@ -711,7 +626,6 @@ void video_demo_thread_entry(ULONG thread_input) #else ret = CDCdrv->Control(CDC200_CONFIGURE_DISPLAY, (uint32_t)(bayer_to_rgb_buffer_pool + TIFF_HDR_SIZE)); #endif - if(ret != 0) { printf("\r\n Error: CDC200 Configuration failed.\r\n"); @@ -719,7 +633,15 @@ void video_demo_thread_entry(ULONG thread_input) } /* Configure Camera */ - ret = CAMERAdrv->Control(CAMERA_SENSOR_CONFIGURE, CAMERA_RESOLUTION_560x560); + ret = CAMERAdrv->Control(CPI_CONFIGURE, 0); + if(ret != ARM_DRIVER_OK) + { + printf("\r\n Error: CAMERA SENSOR Configuration failed.\r\n"); + goto error_poweroff_camera; + } + + /* Control configuration for camera sensor */ + ret = CAMERAdrv->Control(CPI_CAMERA_SENSOR_CONFIGURE, 0); if(ret != ARM_DRIVER_OK) { printf("\r\n Error: CAMERA SENSOR Configuration failed.\r\n"); @@ -727,10 +649,10 @@ void video_demo_thread_entry(ULONG thread_input) } /* Control configuration for camera events */ - ret = CAMERAdrv->Control(CAMERA_EVENTS_CONFIGURE, \ - ARM_CAMERA_CONTROLLER_EVENT_CAMERA_FRAME_VSYNC_DETECTED | \ - ARM_CAMERA_CONTROLLER_EVENT_ERR_CAMERA_FIFO_OVERRUN | \ - ARM_CAMERA_CONTROLLER_EVENT_ERR_CAMERA_FIFO_UNDERRUN); + ret = CAMERAdrv->Control(CPI_EVENTS_CONFIGURE, + ARM_CPI_EVENT_CAMERA_FRAME_VSYNC_DETECTED| \ + ARM_CPI_EVENT_ERR_CAMERA_INPUT_FIFO_OVERRUN | \ + ARM_CPI_EVENT_ERR_CAMERA_OUTPUT_FIFO_OVERRUN); if(ret != ARM_DRIVER_OK) { printf("\r\n Error: CAMERA SENSOR Event Configuration failed.\r\n"); @@ -755,18 +677,19 @@ void video_demo_thread_entry(ULONG thread_input) goto error_poweroff_camera; } -/* Convert the camera captured image into RGB888, - * crop and interpolate the image and - * copy it to Display Frame buffer*/ + /* Convert the camera captured image into RGB888, + * crop and interpolate the image and + * copy it to Display Frame buffer + */ for(;;) { - ret = tx_event_flags_get(&event_flags, \ - CAM_VSYNC_CB_EVENT | \ - CAM_CB_EVENT_ERROR | \ - DISP_CB_EVENT_ERROR, \ - TX_OR_CLEAR, \ - &actual_events, \ - wait_timer_ticks); + ret = tx_event_flags_get(&event_flags, \ + CAM_VSYNC_CB_EVENT | \ + CAM_CB_EVENT_ERROR | \ + DISP_CB_EVENT_ERROR, \ + TX_OR_CLEAR, \ + &actual_events, \ + wait_timer_ticks); if (ret != TX_SUCCESS) { printf("Error: Camera or Display tx_event_flags_get failed.\n"); @@ -780,11 +703,9 @@ void video_demo_thread_entry(ULONG thread_input) goto error_poweroff_camera; } - ret = camera_image_conversion(BAYER_TO_RGB_CONVERSION, - cam_framebuffer_pool, - bayer_to_rgb_buffer_pool, - CAM_FRAME_WIDTH, - CAM_FRAME_HEIGHT); + ret = camera_image_conversion(BAYER_TO_RGB_CONVERSION, cam_framebuffer_pool, + bayer_to_rgb_buffer_pool, CAM_FRAME_WIDTH, + CAM_FRAME_HEIGHT); if(ret != 0) { printf("\r\n Error: CAMERA image conversion failed.\r\n"); @@ -793,26 +714,25 @@ void video_demo_thread_entry(ULONG thread_input) #if IMAGE_CROP_AND_INTERPOLATE_EN ret = crop_and_interpolate((void *)(bayer_to_rgb_buffer_pool + TIFF_HDR_SIZE), - CAM_FRAME_WIDTH, - CAM_FRAME_HEIGHT, - (void *)crop_and_interpolate_buffer_pool, - CRP_FRAME_WIDTH, - CRP_FRAME_HEIGHT, - RGB_BYTES_PER_PIXEL * 8); + CAM_FRAME_WIDTH, CAM_FRAME_HEIGHT, + (void *)crop_and_interpolate_buffer_pool, + CRP_FRAME_WIDTH, CRP_FRAME_HEIGHT, + RGB_BYTES_PER_PIXEL * 8); if(ret != 0) { printf("\r\n Error: CAMERA image crop and interpolate failed.\r\n"); goto error_poweroff_camera; } - for (row = 0, row_location = 0, index =0; row < CRP_FRAME_HEIGHT; row++) { //height + for (row = 0, row_location = 0, index =0; row < CRP_FRAME_HEIGHT; row++) //height + { row_location = row * CRP_FRAME_HEIGHT * RGB_BYTES_PER_PIXEL; - for (col = 0; col < CRP_FRAME_WIDTH; col++) { //width + for (col = 0; col < CRP_FRAME_WIDTH; col++) //width + { lcd_framebuffer_pool[row_location + (col * RGB_BYTES_PER_PIXEL)] = crop_and_interpolate_buffer_pool[index++]; //R lcd_framebuffer_pool[row_location + (col * RGB_BYTES_PER_PIXEL) + 1 ] = crop_and_interpolate_buffer_pool[index++]; //G lcd_framebuffer_pool[row_location + (col * RGB_BYTES_PER_PIXEL) + 2 ] = crop_and_interpolate_buffer_pool[index++]; //B - - } + } } #endif } @@ -821,28 +741,51 @@ void video_demo_thread_entry(ULONG thread_input) /* Power off CAMERA peripheral */ ret = CAMERAdrv->PowerControl(ARM_POWER_OFF); if(ret != ARM_DRIVER_OK) + { printf("\r\n Error: CAMERA Power OFF failed.\r\n"); + } error_poweroff_cdc: /* Power off CDC200 peripheral */ ret = CDCdrv->PowerControl(ARM_POWER_OFF); if(ret != ARM_DRIVER_OK) + { printf("\r\n Error: CDC200 Power OFF failed.\r\n"); + } error_uninitialize_camera: /* Un-initialize CAMERA driver */ ret = CAMERAdrv->Uninitialize(); if(ret != ARM_DRIVER_OK) + { printf("\r\n Error: CAMERA Uninitialize failed.\r\n"); + } error_uninitialize_cdc: /* Un-initialize CDC200 driver */ ret = CDCdrv->Uninitialize(); if(ret != ARM_DRIVER_OK) + { printf("\r\n Error: CDC200 Uninitialize failed.\r\n"); + } + +error_disable_hfosc_clk: + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, CLKEN_HFOSC, false, &service_error_code); + if(error_code != SERVICES_REQ_SUCCESS) + { + printf("SE: MIPI 38.4Mhz(HFOSC) clock disable = %d\n", error_code); + } + +error_disable_100mhz_clk: + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, CLKEN_CLK_100M, false, &service_error_code); + if(error_code != SERVICES_REQ_SUCCESS) + { + printf("SE: MIPI 100MHz clock disable = %d\n", error_code); + } printf("\r\n XXX Camera demo thread is exiting XXX...\r\n"); + /* wait forever */ while(1); } @@ -886,7 +829,6 @@ void tx_application_define(void *first_unused_memory) goto error_delete_byte_pool; } - /* Allocate the stack for thread. */ status = tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); if (status != TX_SUCCESS) @@ -910,17 +852,23 @@ void tx_application_define(void *first_unused_memory) error_release_allocated_byte: status = tx_byte_release((VOID *) pointer); if (status != TX_SUCCESS) + { printf("ERROR: Could not release byte allocate\n"); + } error_delete_event_flag: status = tx_event_flags_delete(&event_flags); if (status != TX_SUCCESS) + { printf("ERROR: Could not delete event flags\n"); + } error_delete_byte_pool: status = tx_byte_pool_delete(&byte_pool_0); if (status != TX_SUCCESS) + { printf("ERROR: Could not delete byte pool\n"); + } while(1); } diff --git a/THREADX/samples/MW_testapp.c b/THREADX/samples/MW_testapp.c new file mode 100644 index 0000000..9e204a9 --- /dev/null +++ b/THREADX/samples/MW_testapp.c @@ -0,0 +1,400 @@ +/* Copyright (C) 2024 Alif Semiconductor - All Rights Reserved. + * Use, distribution and modification of this code is permitted under the + * terms stated in the Alif Semiconductor Software License Agreement + * + * You should have received a copy of the Alif Semiconductor Software + * License Agreement with this file. If not, please write to: + * contact@alifsemi.com, or visit: https://alifsemi.com/license + * + */ + +/**************************************************************************//** + * @file MW_testapp.c + * @author Manoj A Murudi + * @email manoj.murudi@alifsemi.com + * @version V1.0.0 + * @date 28-Jan-2024 + * @brief ThreadX demo app configures the SPI2 instance in master + * mode with Microwire frame format and configures the SPI3 instance + * in slave mode with Microwire frame format. The data transfer + * occurs between master and slave or slave and master based on the + * MASTER_TO_SLAVE_TRANSFER macro. + * @bug None. + * @Note None. + ******************************************************************************/ + +#include "tx_api.h" +#include +#include "string.h" +#include "Driver_SPI.h" +#include "pinconf.h" +#include "RTE_Components.h" +#if defined(RTE_Compiler_IO_STDOUT) +#include "retarget_stdout.h" +#endif /* RTE_Compiler_IO_STDOUT */ + +/* assign 1: To enable master to slave transfer + * 0: To enable slave to master transfer */ +#define MASTER_TO_SLAVE_TRANSFER 1 + +#define MW_THREAD_STACK_SIZE (1024) +#define MW_THREAD_WAIT_TIME (1 * TX_TIMER_TICKS_PER_SECOND) /* wait for 1 sec */ + +static TX_THREAD mw_transfer_thread; +static TX_EVENT_FLAGS_GROUP mw_event_flag; +static ULONG events; + +#define SPI2_CALLBACK_EVENT (1 << 0) /* SPI 2 cb event */ +#define SPI3_CALLBACK_EVENT (1 << 1) /* SPI 3 cb event */ + +#define SPI2 2 /* SPI instance 2 configured Master */ +#define SPI3 3 /* SPI instance 3 configured Slave */ + +extern ARM_DRIVER_SPI ARM_Driver_SPI_(SPI2); +static ARM_DRIVER_SPI *masterDrv = &ARM_Driver_SPI_(SPI2); + +extern ARM_DRIVER_SPI ARM_Driver_SPI_(SPI3); +static ARM_DRIVER_SPI *slaveDrv = &ARM_Driver_SPI_(SPI3); + +/** + * @fn static INT pinmux_config(void) + * @brief SPI2 & SPI3 pinmux configuration. + * @note none. + * @param none. + * @retval execution status. + */ +static INT pinmux_config(void) +{ + INT ret = 0; + + /* pinmux configurations for SPI2 pins (using B version pins) */ + ret = pinconf_set(PORT_9, PIN_2, PINMUX_ALTERNATE_FUNCTION_3, PADCTRL_READ_ENABLE); + if (ret) + { + printf("ERROR: Failed to configure PINMUX for SPI2_MISO_PIN\n"); + return ret; + } + ret = pinconf_set(PORT_9, PIN_3, PINMUX_ALTERNATE_FUNCTION_4, 0); + if (ret) + { + printf("ERROR: Failed to configure PINMUX for SPI2_MOSI_PIN\n"); + return ret; + } + ret = pinconf_set(PORT_9, PIN_4, PINMUX_ALTERNATE_FUNCTION_3, 0); + if (ret) + { + printf("ERROR: Failed to configure PINMUX for SPI2_CLK_PIN\n"); + return ret; + } + ret = pinconf_set(PORT_9, PIN_5, PINMUX_ALTERNATE_FUNCTION_3, 0); + if (ret) + { + printf("ERROR: Failed to configure PINMUX for SPI2_SS_PIN\n"); + return ret; + } + + /* pinmux configurations for SPI3 pins (using B version pins) */ + ret = pinconf_set(PORT_12, PIN_4, PINMUX_ALTERNATE_FUNCTION_2, 0); + if (ret) + { + printf("ERROR: Failed to configure PINMUX for SPI3_MISO_PIN\n"); + return ret; + } + ret = pinconf_set(PORT_12, PIN_5, PINMUX_ALTERNATE_FUNCTION_2, PADCTRL_READ_ENABLE); + if (ret) + { + printf("ERROR: Failed to configure PINMUX for SPI3_MOSI_PIN\n"); + return ret; + } + ret = pinconf_set(PORT_12, PIN_6, PINMUX_ALTERNATE_FUNCTION_2, PADCTRL_READ_ENABLE); + if (ret) + { + printf("ERROR: Failed to configure PINMUX for SPI3_CLK_PIN\n"); + return ret; + } + ret = pinconf_set(PORT_12, PIN_7, PINMUX_ALTERNATE_FUNCTION_3, PADCTRL_READ_ENABLE); + if (ret) + { + printf("ERROR: Failed to configure PINMUX for SPI3_SS_PIN\n"); + return ret; + } + + return 0; +} + +/** + * @fn void SPI2_Callback_func (UINT event) + * @brief SPI2 call back function. + * @note none. + * @param event: SPI event. + * @retval None + */ +static void SPI2_Callback_func (UINT event) +{ + if (event == ARM_SPI_EVENT_TRANSFER_COMPLETE) + { + tx_event_flags_set(&mw_event_flag, SPI2_CALLBACK_EVENT, TX_OR); + } +} + +/** + * @fn void SPI3_Callback_func (UINT event) + * @brief SPI3 call back function. + * @note none. + * @param event: SPI event. + * @retval None + */ +static void SPI3_Callback_func (UINT event) +{ + if (event == ARM_SPI_EVENT_TRANSFER_COMPLETE) + { + tx_event_flags_set(&mw_event_flag, SPI3_CALLBACK_EVENT, TX_OR); + } +} + +/** + * @fn static void MW_Demo_thread(ULONG thread_input) + * @brief demo application function for microwire data transfer. + * @note none. + * @param thread_input. + * @retval none. + */ +static void MW_Demo_thread(ULONG thread_input) +{ + UINT master_control, slave_control, ret, baudrate = 1000000; + INT status; + ARM_SPI_STATUS spi2_status, spi3_status; + + /* Single buffer is used to store both control code and data. + * Therefore, Buffer width size should be of 4 bytes irrespective of frame format size + * and control code size (control code size can be configured in RTE_Device.h) */ + UINT master_tx_buff[4], slave_rx_buff[4] = {0}; +#if !MASTER_TO_SLAVE_TRANSFER + UINT master_rx_buff[4] = {0}, slave_tx_buff[4]; +#endif + + printf("Start of MicroWire demo application \n"); + + /* SPI instances pinmux initialization */ + status = pinmux_config(); + if (status) + { + printf("ERROR: Failed in SPI pinmux and pinpad config \n"); + return; + } + + /* SPI2 master instance initialization */ + status = masterDrv->Initialize(SPI2_Callback_func); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed to initialize SPI2 \n"); + return; + } + + status = masterDrv->PowerControl(ARM_POWER_FULL); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed to power SPI2 \n"); + goto error_spi2_uninitialize; + } + + master_control = (ARM_SPI_MODE_MASTER | ARM_SPI_SS_MASTER_HW_OUTPUT | ARM_SPI_MICROWIRE | ARM_SPI_DATA_BITS(32)); + + status = masterDrv->Control(master_control, baudrate); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed to configure SPI2\n"); + goto error_spi2_power_off; + } + + /* SPI3 slave instance initialization */ + status = slaveDrv->Initialize(SPI3_Callback_func); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed to initialize SPI3 \n"); + return; + } + + status = slaveDrv->PowerControl(ARM_POWER_FULL); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed to power SPI3 \n"); + goto error_spi3_uninitialize; + } + + slave_control = (ARM_SPI_MODE_SLAVE | ARM_SPI_MICROWIRE | ARM_SPI_DATA_BITS(32)); + + status = slaveDrv->Control(slave_control, NULL); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed to configure SPI3\n"); + goto error_spi3_power_off; + } + + status = masterDrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_ACTIVE); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed to configure SPI2\n"); + goto error_spi2_power_off; + } + +#if MASTER_TO_SLAVE_TRANSFER + + printf("\nData transfer from master to slave \n"); + + master_tx_buff[0] = 0x1111; /* control word 1 */ + master_tx_buff[1] = 0x11111111; /* data 1 */ + master_tx_buff[2] = 0x2222; /* control word 2 */ + master_tx_buff[3] = 0x22222222; /* data 2 */ + + /* The second parameter should be the total number of data to be transferred, + * excluding the control frame number. */ + status = slaveDrv->Receive(slave_rx_buff, 2); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed SPI3 to configure as rx\n"); + goto error_spi3_power_off; + } + + /* The second parameter should be the total number of data to be transferred, + * excluding the control frame number. */ + status = masterDrv->Send(master_tx_buff, 2); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed SPI2 to configure as tx\n"); + goto error_spi2_power_off; + } + +#else + + /* assign control codes to master tx buffer */ + master_tx_buff[0] = 0x1111; /* control word 1 */ + master_tx_buff[1] = 0x2222; /* control word 2 */ + + /* assign slave tx buffer */ + slave_tx_buff[0] = 0x11111111; /* data 1 */ + slave_tx_buff[1] = 0x22222222; /* data 2 */ + + printf("\nData transfer from slave to master \n"); + + /* The third parameter should be the total number of data to be transferred, + * excluding the control frame number. */ + status = slaveDrv->Transfer(slave_tx_buff, slave_rx_buff, 2); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed SPI3 to configure as tx\n"); + goto error_spi3_power_off; + } + + /* The third parameter should be the total number of data to be transferred, + * excluding the control frame number. */ + status = masterDrv->Transfer(master_tx_buff, master_rx_buff, 2); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed SPI2 to configure as rx\n"); + goto error_spi2_power_off; + } + +#endif + + ret = tx_event_flags_get (&mw_event_flag, SPI2_CALLBACK_EVENT|SPI3_CALLBACK_EVENT, TX_AND_CLEAR, &events, MW_THREAD_WAIT_TIME); + if (ret != TX_SUCCESS) + { + printf("ERROR : event not received, timeout happened \n"); + goto error_spi2_power_off; + } + else + { + printf("Data Transfer completed\n"); + } + + spi2_status = masterDrv->GetStatus(); + spi3_status = slaveDrv->GetStatus(); + while((spi2_status.busy == 1) || (spi3_status.busy == 1)) + { + spi2_status = masterDrv->GetStatus(); + spi3_status = slaveDrv->GetStatus(); + } + + masterDrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_INACTIVE); + if (status != ARM_DRIVER_OK) + { + printf("ERROR: Failed to configure SPI2\n"); + goto error_spi2_power_off; + } + +#if MASTER_TO_SLAVE_TRANSFER + (memcmp(master_tx_buff, slave_rx_buff, 4) == 0) ? printf("Master tx & Slave rx buffers are same\n") : \ + printf("Master tx & Slave rx rx buffers are different\n"); + +#else + (memcmp(master_tx_buff, slave_rx_buff, 2) == 0) ? printf("Master tx & Slave rx buffers are same\n") : \ + printf("Master tx & Slave rx buffers are different\n"); + (memcmp(slave_tx_buff, master_rx_buff, 2) == 0) ? printf("Slave tx & Master rx buffers are same\n") : \ + printf("Slave tx & Master rx buffers are different\n"); + +#endif + +error_spi2_power_off : + status = masterDrv->PowerControl(ARM_POWER_OFF); + if (status != ARM_DRIVER_OK) + printf("Error in SPI2 Power Off \n"); + +error_spi2_uninitialize : + status = masterDrv->Uninitialize(); + if (status != ARM_DRIVER_OK) + printf("Error in SPI2 Uninitialize \n"); + +error_spi3_power_off : + status = slaveDrv->PowerControl(ARM_POWER_OFF); + if (status != ARM_DRIVER_OK) + printf("Error in SPI3 Power Off \n"); + +error_spi3_uninitialize : + status = slaveDrv->Uninitialize(); + if (status != ARM_DRIVER_OK) + printf("Error in SPI3 Uninitialize \n"); + + printf("\nEnd of MicroWire demo application \n"); +} + +/* Define main entry point. */ +int main () +{ + #if defined(RTE_Compiler_IO_STDOUT_User) + INT ret; + ret = stdout_init(); + if(ret != ARM_DRIVER_OK) + { + while(1) + { + } + } + #endif + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + +/* Define what the initial system looks like. */ +void tx_application_define (void *first_unused_memory) +{ + UINT ret; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + /* Create a event flag for mw group. */ + ret = tx_event_flags_create (&mw_event_flag, "MW_EVENT_FLAG"); + if (ret != TX_SUCCESS) + { + printf("failed to create mw event flag\r\n"); + } + + /* Create the main thread. */ + ret = tx_thread_create (&mw_transfer_thread, "TRANSFER DEMO THREAD", MW_Demo_thread, 0, + first_unused_memory, MW_THREAD_STACK_SIZE, 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + if (ret != TX_SUCCESS) + { + printf("failed to create mw demo thread\r\n"); + } +} diff --git a/THREADX/samples/PDM_testApp.c b/THREADX/samples/PDM_testApp.c index fe06caa..fe95556 100644 --- a/THREADX/samples/PDM_testApp.c +++ b/THREADX/samples/PDM_testApp.c @@ -48,8 +48,8 @@ #include "Driver_PDM.h" #include "pinconf.h" #include "RTE_Components.h" -#if defined(RTE_Compiler_IO_STDOUT) -#include "retarget_stdout.h" +#if defined(RTE_Compiler_IO_STDOUT) +#include "retarget_stdout.h" #endif /* RTE_Compiler_IO_STDOUT */ @@ -65,6 +65,18 @@ #define CHANNEL_4 4 #define CHANNEL_5 5 +/* PDM Channel 4 configurations */ +#define CH4_PHASE 0x0000001F +#define CH4_GAIN 0x0000000D +#define CH4_PEAK_DETECT_TH 0x00060002 +#define CH4_PEAK_DETECT_ITV 0x0004002D + +/* PDM Channel 5 configurations */ +#define CH5_PHASE 0x00000003 +#define CH5_GAIN 0x00000013 +#define CH5_PEAK_DETECT_TH 0x00060002 +#define CH5_PEAK_DETECT_ITV 0x00020027 + /* PDM driver instance */ extern ARM_DRIVER_PDM Driver_PDM; static ARM_DRIVER_PDM *PDMdrv = &Driver_PDM; @@ -179,34 +191,57 @@ void pdm_demo_thread_entry(ULONG thread_input) } /* To select the PDM channel 4 and channel 5 */ - ret = PDMdrv->Control(ARM_PDM_SELECT_CHANNEL, (ARM_PDM_MASK_CHANNEL_4 | ARM_PDM_MASK_CHANNEL_5)); + ret = PDMdrv->Control(ARM_PDM_SELECT_CHANNEL, ARM_PDM_MASK_CHANNEL_4 |ARM_PDM_MASK_CHANNEL_5, NULL); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM channel select control failed\n"); goto error_poweroff; } /* Select Standard voice PDM mode */ - ret = PDMdrv->Control(ARM_PDM_MODE, ARM_PDM_MODE_STANDARD_VOICE_512_CLK_FRQ); + ret = PDMdrv->Control(ARM_PDM_MODE, ARM_PDM_MODE_STANDARD_VOICE_512_CLK_FRQ, NULL); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM Standard voice control mode failed\n"); goto error_poweroff; } /* Select the DC blocking IIR filter */ - ret = PDMdrv->Control(ARM_PDM_BYPASS_IIR_FILTER, ENABLE); + ret = PDMdrv->Control(ARM_PDM_BYPASS_IIR_FILTER, ENABLE, NULL); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM DC blocking IIR control failed\n"); goto error_poweroff; } - /* Channel 4 configuration values */ - pdm_coef_reg.ch_num = CHANNEL_4; /* Channel 4 */ + /* Set Channel 4 Phase value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PHASE, CHANNEL_4, CH4_PHASE); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + /* Set Channel 4 Gain value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_GAIN, CHANNEL_4, CH4_GAIN); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + /* Set Channel 4 Peak detect threshold value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PEAK_DETECT_TH, CHANNEL_4, CH4_PEAK_DETECT_TH); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + /* Set Channel 4 Peak detect ITV value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PEAK_DETECT_ITV, CHANNEL_4, CH4_PEAK_DETECT_ITV); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + pdm_coef_reg.ch_num = 4; memcpy(pdm_coef_reg.ch_fir_coef, ch4_fir, sizeof(pdm_coef_reg.ch_fir_coef)); /* Channel 4 fir coefficient */ pdm_coef_reg.ch_iir_coef = 0x00000004; /* Channel IIR Filter Coefficient */ - pdm_coef_reg.ch_phase = 0x0000001F; /* Channel Phase Control */ - pdm_coef_reg.ch_gain = 0x0000000D; /* Channel gain control */ - pdm_coef_reg.ch_peak_detect_th = 0x00060002; /* Channel Peak Detector Threshold */ - pdm_coef_reg.ch_peak_detect_itv = 0x0004002D; /* Channel Peak Detector Interval */ ret = PDMdrv->Config(&pdm_coef_reg); if(ret != ARM_DRIVER_OK){ @@ -214,21 +249,38 @@ void pdm_demo_thread_entry(ULONG thread_input) goto error_uninitialize; } - /* Channel 5 configuration values */ - pdm_coef_reg.ch_num = CHANNEL_5; /* Channel 5 */ - memcpy(pdm_coef_reg.ch_fir_coef, ch5_fir, sizeof(pdm_coef_reg.ch_fir_coef)); /* Channel 5 fir coefficient */ - pdm_coef_reg.ch_iir_coef = 0x00000004; /* Channel IIR Filter Coefficient */ - pdm_coef_reg.ch_phase = 0x00000003; /* Channel Phase Control */ - pdm_coef_reg.ch_gain = 0x00000013; /* Channel gain control */ - pdm_coef_reg.ch_peak_detect_th = 0x00060002; /* Channel Peak Detector Threshold */ - pdm_coef_reg.ch_peak_detect_itv = 0x00020027; /* Channel Peak Detector Interval */ + /* Set Channel 5 Phase value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PHASE, CHANNEL_5, CH5_PHASE); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } - ret = PDMdrv->Config(&pdm_coef_reg); + /* Set Channel 5 Gain value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_GAIN, CHANNEL_5, CH5_GAIN); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM Channel_Config failed\n"); goto error_uninitialize; } + /* Set Channel 5 Peak detect threshold value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PEAK_DETECT_TH, CHANNEL_5, CH5_PEAK_DETECT_TH); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + /* Set Channel 5 Peak detect ITV value */ + ret = PDMdrv->Control(ARM_PDM_CHANNEL_PEAK_DETECT_ITV, CHANNEL_5, CH5_PEAK_DETECT_ITV); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: PDM Channel_Config failed\n"); + goto error_uninitialize; + } + + pdm_coef_reg.ch_num = 5; + memcpy(pdm_coef_reg.ch_fir_coef, ch5_fir, sizeof(pdm_coef_reg.ch_fir_coef)); /* Channel 5 fir coefficient */ + pdm_coef_reg.ch_iir_coef = 0x00000004; /* Channel IIR Filter Coefficient */ + ret = PDMdrv->Config(&pdm_coef_reg); if(ret != ARM_DRIVER_OK){ printf("\r\n Error: PDM Channel_Config failed\n"); diff --git a/THREADX/samples/TSENS_testapp.c b/THREADX/samples/TSENS_testapp.c new file mode 100644 index 0000000..1501c53 --- /dev/null +++ b/THREADX/samples/TSENS_testapp.c @@ -0,0 +1,266 @@ +/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved. + * Use, distribution and modification of this code is permitted under the + * terms stated in the Alif Semiconductor Software License Agreement + * + * You should have received a copy of the Alif Semiconductor Software + * License Agreement with this file. If not, please write to: + * contact@alifsemi.com, or visit: https://alifsemi.com/license + */ +/**************************************************************************//** + * @file : TSENS_testapp.c.c + * @author : Prabhakar kumar + * @email : prabhakar.kumar@alifsemi.com + * @version : V1.0.0 + * @date : 21-AUG-2023 + * @brief : ThreadX demo application code for ADC driver temperature sensor + * - Internal input of temperature in analog signal corresponding + * output is digital value. + * - Converted digital value are stored in user provided memory + * address. + * + * Hardware Connection: + * Common temperature sensor is internally connected to ADC12 6th channel + * of each instance. + * no hardware setup required. + * @bug : None. + * @Note : None. + ******************************************************************************/ + +/* System Includes */ +#include +#include "tx_api.h" +#include "system_utils.h" + +/* include for ADC Driver */ +#include "Driver_ADC.h" +#include "temperature.h" + +#include "se_services_port.h" +#include "RTE_Components.h" +#if defined(RTE_Compiler_IO_STDOUT) +#include "retarget_stdout.h" +#endif /* RTE_Compiler_IO_STDOUT */ + +#define ADC_CONVERSION ARM_ADC_SINGLE_SHOT_CH_CONV + +void tsens_demo_Thread_entry(ULONG thread_input); + +/* Define the ThreadX object control blocks... */ +#define DEMO_STACK_SIZE 1024 +#define TX_ADC_INT_AVG_SAMPLE_RDY 0x01 + +TX_THREAD tsens_thread; +TX_EVENT_FLAGS_GROUP event_flags_adc; + +/* Instance for ADC12 */ +extern ARM_DRIVER_ADC Driver_ADC122; +static ARM_DRIVER_ADC *ADCdrv = &Driver_ADC122; + +#define TEMPERATURE_SENSOR ARM_ADC_CHANNEL_6 +#define NUM_CHANNELS (8) + +/* Demo purpose Channel_value*/ +UINT adc_sample[NUM_CHANNELS]; + +volatile UINT num_samples = 0; + +/* + * @func : void adc_conversion_callback(uint32_t event, uint8_t channel, uint32_t sample_output) + * @brief : adc conversion isr callback + * @return : NONE +*/ +static void adc_conversion_callback(uint32_t event, uint8_t channel, uint32_t sample_output) +{ + if (event & ARM_ADC_EVENT_CONVERSION_COMPLETE) + { + num_samples += 1; + + /* Store the value for the respective channels */ + adc_sample[channel] = sample_output; + + /* Sample ready Wake up Thread. */ + tx_event_flags_set(&event_flags_adc, TX_ADC_INT_AVG_SAMPLE_RDY, TX_OR); + } +} + +/** + * @func : void tsens_demo_thread_entry(ULONG thread_input) + * @brief : tsens demo (temperature sensor) + * - test to verify the temperature sensor of adc. + * - Internal input of temperature in analog signal corresponding + * output is digital value. + * - converted value is the allocated user memory address. + * @parameter[1] : thread_input : thread input + * @return : NONE +*/ +void tsens_demo_thread_entry(ULONG thread_input) +{ + ULONG events = 0; + UINT ret = 0; + UINT error_code = SERVICES_REQ_SUCCESS; + UINT service_error_code; + float temp; + ARM_DRIVER_VERSION version; + + (void) thread_input; + + /* Initialize the SE services */ + se_services_port_init(); + + /* enable the 160 MHz clock */ + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, + /*clock_enable_t*/ CLKEN_CLK_160M, + /*bool enable */ true, + &service_error_code); + if (error_code) + { + printf("SE Error: 160 MHz clk enable = %d\n", error_code); + return; + } + + printf("\r\n >>> ADC demo threadX starting up!!! <<< \r\n"); + + version = ADCdrv->GetVersion(); + printf("\r\n ADC version api:%X driver:%X...\r\n",version.api, version.drv); + + /* Initialize ADC driver */ + ret = ADCdrv->Initialize(adc_conversion_callback); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC init failed\n"); + goto error_uninitialize; + } + + /* Power control ADC */ + ret = ADCdrv->PowerControl(ARM_POWER_FULL); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC Power up failed\n"); + goto error_uninitialize; + } + + /* set conversion mode */ + ret = ADCdrv->Control(ARM_ADC_CONVERSION_MODE_CTRL, ADC_CONVERSION); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC select conversion mode failed\n"); + goto error_poweroff; + } + + /* set initial channel */ + ret = ADCdrv->Control(ARM_ADC_CHANNEL_INIT_VAL, TEMPERATURE_SENSOR); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC channel init failed\n"); + goto error_poweroff; + } + + printf(">>> Allocated memory buffer Address is 0x%X <<<\n",(uint32_t)(adc_sample + TEMPERATURE_SENSOR)); + /* Start ADC */ + ret = ADCdrv->Start(); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC Start failed\n"); + goto error_poweroff; + } + + /* wait for num_samples */ + while (num_samples == 0); + + /* wait till conversion comes ( isr callback ) */ + ret = tx_event_flags_get(&event_flags_adc, TX_ADC_INT_AVG_SAMPLE_RDY, + TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + if (ret != TX_SUCCESS) { + printf("Error: ADC tx_event_flags_get\n"); + goto error_poweroff; + } + + /* Reading temperature */ + temp = get_temperature(adc_sample[TEMPERATURE_SENSOR]); + if (temp == ARM_DRIVER_ERROR) { + printf("\r\n Error: Temperature is outside range\n"); + goto error_poweroff; + } + else + { + printf("\n Current temp %.1f°C\n",temp); + } + + /* Stop ADC */ + ret = ADCdrv->Stop(); + if (ret != ARM_DRIVER_OK){ + printf("\r\n Error: ADC Stop failed\n"); + goto error_poweroff; + } + + printf("\n >>> ADC conversion completed \n"); + printf(" Converted value are stored in user allocated memory address.\n"); + printf("\n ---END--- \r\n wait forever >>> \n"); + while(1); + +error_poweroff: + + /* Power off ADC peripheral */ + ret = ADCdrv->PowerControl(ARM_POWER_OFF); + if (ret != ARM_DRIVER_OK) + { + printf("\r\n Error: ADC Power OFF failed.\r\n"); + } + +error_uninitialize: + + /* Un-initialize ADC driver */ + ret = ADCdrv->Uninitialize(); + if (ret != ARM_DRIVER_OK) + { + printf("\r\n Error: ADC Uninitialize failed.\r\n"); + } + /* disable the 160MHz clock */ + error_code = SERVICES_clocks_enable_clock(se_services_s_handle, + /*clock_enable_t*/ CLKEN_CLK_160M, + /*bool enable */ false, + &service_error_code); + if (error_code) + { + printf("SE Error: 160 MHz clk disable = %d\n", error_code); + return; + } + + printf("\r\n ADC demo exiting...\r\n"); +} + +/* Define main entry point. */ +int main() +{ + #if defined(RTE_Compiler_IO_STDOUT_User) + int32_t ret; + ret = stdout_init(); + if(ret != ARM_DRIVER_OK) + { + while(1) + { + } + } + #endif + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + +/* Define what the initial system looks like. */ +void tx_application_define(void *first_unused_memory) +{ + INT status; + + /* Create the event flags group used by ADC thread */ + status = tx_event_flags_create(&event_flags_adc, "event flags ADC"); + if (status != TX_SUCCESS) + { + printf("Could not create event flags\n"); + return; + } + + /* Create the main thread. */ + status = tx_thread_create(&tsens_thread, "tsens_thread", tsens_demo_thread_entry, 0, + first_unused_memory, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + if (status != TX_SUCCESS) + { + printf("Could not create thread\n"); + return; + } +} diff --git a/THREADX/samples/bayer2rgb.c b/THREADX/samples/bayer2rgb.c index fe771bd..f5d2644 100644 --- a/THREADX/samples/bayer2rgb.c +++ b/THREADX/samples/bayer2rgb.c @@ -233,9 +233,5 @@ int32_t bayer_to_RGB(uint8_t *src, uint8_t *dest, \ #endif /* end of ENABLE_16_BIT_VERSION */ } - printf("\n Bayer to RGB Converted Tiff Color Image Memory Address is :"); - printf("\n \t starting_addr: 0x%X \r\n \t ending_addr : 0x%X\n", \ - (uint32_t) dest, (uint32_t) (dest+out_size-1)); - return 0; } diff --git a/THREADX/samples/dac_testapp.c b/THREADX/samples/dac_testapp.c index a0887fe..1c70185 100644 --- a/THREADX/samples/dac_testapp.c +++ b/THREADX/samples/dac_testapp.c @@ -133,6 +133,20 @@ void dac_demo_Thread_entry(ULONG thread_input) goto error_uninitialize; } + /* Set DAC IBAIS output current */ + ret = DACdrv->Control(ARM_DAC_SELECT_IBIAS_OUTPUT, ARM_DAC_1500UA_OUT_CUR); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: Setting DAC output current failed failed\n"); + goto error_uninitialize; + } + + /* Set DAC capacitance */ + ret = DACdrv->Control(ARM_DAC_CAPACITANCE_HP_MODE, ARM_DAC_8PF_CAPACITANCE); + if(ret != ARM_DRIVER_OK){ + printf("\r\n Error: Setting DAC capacitance failed\n"); + goto error_uninitialize; + } + /* start dac */ ret = DACdrv->Start(); if(ret != ARM_DRIVER_OK){ diff --git a/THREADX/samples/image_processing.c b/THREADX/samples/image_processing.c index 6d3e802..dde6a37 100644 --- a/THREADX/samples/image_processing.c +++ b/THREADX/samples/image_processing.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Alif Semiconductor - All Rights Reserved. +/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved. * Use, distribution and modification of this code is permitted under the * terms stated in the Alif Semiconductor Software License Agreement * @@ -18,268 +18,219 @@ * @bug None. * @Note None. ******************************************************************************/ + #include #include +#include +#include +#include +#include + +#include "RTE_Components.h" + +#if __ARM_FEATURE_MVE & 1 +#include +#endif + +#include "RTE_Components.h" /*error status*/ #define FRAME_FORMAT_NOT_SUPPORTED -1 #define FRAME_OUT_OF_RANGE -2 -/** - \fn int frame_crop(void *input_fb, - uint32_t ip_row_size, - uint32_t ip_col_size, - uint32_t row_start, - uint32_t col_start, - void *output_fb, - uint32_t op_row_size, - uint32_t op_col_size, - uint32_t bpp) - \brief Crop the frame to the Given row and column Size. - \param[in] input_fb address of the input frame buffer. - \param[in] ip_row_size input row size. - \param[in] ip_col_size input column size. - \param[in] row_start start index of the row. - \param[in] col_start start index of the column. - \param[in] output_fb address of the output frame buffer. - \param[in] op_row_size output row size. - \param[in] op_col_size output column size. - \param[in] bpp bits per pixel. - \return return error status. zero for success negative value for error. -*/ -int frame_crop(void *input_fb, - uint32_t ip_row_size, - uint32_t ip_col_size, - uint32_t row_start, - uint32_t col_start, - void *output_fb, - uint32_t op_row_size, - uint32_t op_col_size, +int frame_crop(const void *input_fb, uint32_t ip_row_size, + uint32_t ip_col_size, uint32_t row_start, + uint32_t col_start, void *output_fb, + uint32_t op_row_size, uint32_t op_col_size, uint32_t bpp) { - uint32_t *op_fb = NULL, *ip_fb_row = NULL; - uint8_t *ip_fb = NULL, *ip8_fb_row = NULL, *op8_fb = NULL; - uint32_t col_cnt, row_cnt; - - /*Checking the boundary*/ - if(((row_start + op_row_size) > ip_row_size) || ((col_start + op_col_size) > ip_col_size)) - return FRAME_OUT_OF_RANGE; - - /*updating the input frame column start*/ - ip_fb = (col_start * ip_row_size * (bpp / 8)) + (uint8_t *)input_fb ; - - - if((32 % bpp) == 0) { - /*8bit and 16bit bpp will be handled here.*/ - op_fb = (uint32_t *)output_fb; - - - for(col_cnt = 0; col_cnt < op_col_size; ++col_cnt) { - - /*update row address*/ - ip_fb_row = (uint32_t *)((row_start * (bpp / 8)) + ip_fb); - - for(row_cnt = 0; row_cnt < (op_row_size / (32 / bpp)); ++row_cnt) - op_fb[row_cnt] = ip_fb_row[row_cnt]; - - /*copy remaining pixels*/ - if(op_row_size % (32 / bpp)) - op_fb[row_cnt] = ip_fb_row[row_cnt]; - - /*update fb*/ - ip_fb = (ip_row_size * (bpp / 8)) + ip_fb; - op_fb = (uint32_t *)((op_row_size * (bpp / 8)) + (uint8_t *)op_fb); - } - } else { - /*24bit bpp will be handled here.*/ - op8_fb = (uint8_t *)output_fb; - - - for(col_cnt = 0; col_cnt < op_col_size; ++col_cnt) { - - /*update row address*/ - ip8_fb_row = (row_start * (bpp / 8)) + ip_fb; - - /*copy pixels*/ - for(row_cnt = 0; row_cnt < (op_row_size * (bpp / 8)); ++row_cnt) - op8_fb[row_cnt] = ip8_fb_row[row_cnt]; - - /*update fb*/ - ip_fb = ((ip_row_size * (bpp / 8)) + ip_fb); - op8_fb = ((op_row_size * (bpp / 8)) + op8_fb); - } - - } - - return 0; + uint8_t *op_fb; + uint8_t *ip_fb; + + //Checking the boundary + if(((row_start + op_row_size) > ip_row_size) || ((col_start + op_col_size) > ip_col_size)) + { + return FRAME_OUT_OF_RANGE; + } + + // Check for no cropping + if (row_start == 0 && col_start == 0 && ip_row_size == op_row_size && ip_col_size == op_col_size) + { + // No-op if cropping and in-place + if (input_fb != output_fb) + { + memcpy(output_fb, input_fb, ip_row_size * op_row_size * (bpp / 8)); + } + return 0; + } + + //updating the input frame column start + ip_fb = (uint8_t *)input_fb + (col_start * ip_row_size * (bpp / 8)); + + op_fb = output_fb; + + for(uint32_t col_cnt = 0; col_cnt < op_col_size; ++col_cnt) + { + //update row address + const uint8_t *ip_fb_row = ip_fb + row_start * (bpp / 8); + + memmove(op_fb, ip_fb_row, op_row_size * (bpp / 8)); + + //update fb + ip_fb += (ip_row_size * (bpp / 8)); + op_fb += (op_row_size * (bpp / 8)); + } + + return 0; } -/** - \fn int resize_image(const uint8_t *srcImage, - int srcWidth, - int srcHeight, - uint8_t *dstImage, - int dstWidth, - int dstHeight, - uint32_t bpp) - \brief Resize image using interpolation method. - \param[in] srcImage address of the input frame buffer. - \param[in] srcWidth input row size. - \param[in] srcHeight input column size. - \param[in] dstImage address of the output frame buffer. - \param[in] dstWidth output row size. - \param[in] dstHeight output column size. - \param[in] pixel_size_B number of bytes per pixel. - \return return error status. zero for success negative value for error. -*/ -int resize_image(const uint8_t *srcImage, - int srcWidth, - int srcHeight, - uint8_t *dstImage, - int dstWidth, - int dstHeight, - int pixel_size_B) +int resize_image(const uint8_t *srcImage, int srcWidth, + int srcHeight, uint8_t *dstImage, + int dstWidth, int dstHeight, int pixel_size_B) { - int FRAC_BITS = 14; - int FRAC_VAL = (1 << FRAC_BITS); - int FRAC_MASK = (FRAC_VAL - 1); - - uint32_t src_x_accum, src_y_accum; // accumulators and fractions for scaling the image - uint32_t x_frac, nx_frac, y_frac, ny_frac; - int x, y, ty; - - if (srcHeight < 2) { - return FRAME_OUT_OF_RANGE; - } - - /*start at 1/2 pixel in to account for integer downsampling which might miss pixels*/ - src_y_accum = FRAC_VAL / 2; - const uint32_t src_x_frac = (srcWidth * FRAC_VAL) / dstWidth; - const uint32_t src_y_frac = (srcHeight * FRAC_VAL) / dstHeight; - - /*from here out, *3 b/c RGB*/ - srcWidth *= pixel_size_B; - - /*srcHeight not used for indexing dstWidth still needed as is dstHeight shouldn't be scaled*/ - const uint8_t *s; - uint8_t *d; - - for (y = 0; y < dstHeight; y++) { - /*do indexing computations*/ - ty = src_y_accum >> FRAC_BITS; // src y - y_frac = src_y_accum & FRAC_MASK; - src_y_accum += src_y_frac; - ny_frac = FRAC_VAL - y_frac; // y fraction and 1.0 - y fraction - - s = &srcImage[ty * srcWidth]; - d = &dstImage[y * dstWidth * pixel_size_B]; //not scaled above - /* start at 1/2 pixel in to account for integer downsampling which might miss pixels*/ - src_x_accum = FRAC_VAL / 2; - for (x = 0; x < dstWidth; x++) { - uint32_t tx, p00, p01, p10, p11; - /*do indexing computations*/ - tx = (src_x_accum >> FRAC_BITS) * pixel_size_B; - x_frac = src_x_accum & FRAC_MASK; - nx_frac = FRAC_VAL - x_frac; // x fraction and 1.0 - x fraction - src_x_accum += src_x_frac; - - /*interpolate and write out*/ - for (int color = 0; color < pixel_size_B; - color++) // do pixel_size_B times for pixel_size_B colors - { - p00 = s[tx]; - p10 = s[tx + pixel_size_B]; - p01 = s[tx + srcWidth]; - p11 = s[tx + srcWidth + pixel_size_B]; - p00 = ((p00 * nx_frac) + (p10 * x_frac) + FRAC_VAL / 2) >> FRAC_BITS; // top line - p01 = ((p01 * nx_frac) + (p11 * x_frac) + FRAC_VAL / 2) >> FRAC_BITS; // bottom line - p00 = ((p00 * ny_frac) + (p01 * y_frac) + FRAC_VAL / 2) >> FRAC_BITS; //top + bottom - *d++ = (uint8_t)p00; // store new pixel - /*ready next loop*/ - tx++; - } - } // for x - } // for y - return 0; -} - -/* - \fn void calculate_crop_dims(uint32_t srcWidth, - uint32_t srcHeight, - uint32_t dstWidth, - uint32_t dstHeight, - uint32_t *cropWidth, - uint32_t *cropHeight) - \brief calculate the crop dimension. - \param[in] srcWidth input row size. - \param[in] srcHeight input column size. - \param[in] dstWidth output row size. - \param[in] dstHeight output column size. - \param[in] cropWidth pointer to the variable to store crop row size. - \param[in] cropHeight pointer to the variable to store crop column size. -*/ -void calculate_crop_dims(uint32_t srcWidth, - uint32_t srcHeight, - uint32_t dstWidth, - uint32_t dstHeight, - uint32_t *cropWidth, - uint32_t *cropHeight) + if (pixel_size_B != 3) + { + abort(); + } + + // Copied from ei_camera.cpp in firmware-eta-compute + // Modified for RGB888 + // This needs to be < 16 or it won't fit. Cortex-M4 only has SIMD for signed multiplies +#define FRAC_BITS 14 + const int FRAC_VAL = (1 << FRAC_BITS); + const int FRAC_MASK = (FRAC_VAL - 1); + + uint32_t src_x_accum, src_y_accum; // accumulators and fractions for scaling the image + uint32_t x_frac, nx_frac, y_frac, ny_frac; + int x, y, ty; + + if (srcHeight < 2) + { + return FRAME_OUT_OF_RANGE; + } + + // start at 1/2 pixel in to account for integer downsampling which might miss pixels + src_y_accum = FRAC_VAL / 2; + const uint32_t src_x_frac = (srcWidth * FRAC_VAL) / dstWidth; + const uint32_t src_y_frac = (srcHeight * FRAC_VAL) / dstHeight; + + //from here out, *3 b/c RGB + srcWidth *= pixel_size_B; + + //srcHeight not used for indexing + //dstWidth still needed as is + //dstHeight shouldn't be scaled + + const uint8_t *s; + uint8_t *d; + + for (y = 0; y < dstHeight; y++) + { + // do indexing computations + ty = src_y_accum >> FRAC_BITS; // src y + y_frac = src_y_accum & FRAC_MASK; + src_y_accum += src_y_frac; + ny_frac = FRAC_VAL - y_frac; // y fraction and 1.0 - y fraction + + s = &srcImage[ty * srcWidth]; + d = &dstImage[y * dstWidth * pixel_size_B]; //not scaled above + // start at 1/2 pixel in to account for integer downsampling which might miss pixels + src_x_accum = FRAC_VAL / 2; + for (x = 0; x < dstWidth; x++) + { + uint32_t tx; + // do indexing computations + tx = (src_x_accum >> FRAC_BITS) * pixel_size_B; + x_frac = src_x_accum & FRAC_MASK; + nx_frac = FRAC_VAL - x_frac; // x fraction and 1.0 - x fraction + src_x_accum += src_x_frac; +#ifndef __ICCARM__ + __builtin_prefetch(&s[tx + 64]); + __builtin_prefetch(&s[tx + srcWidth + 64]); +#endif + +#if __ARM_FEATURE_MVE & 1 + uint32x4_t p00 = vldrbq_u32(&s[tx]); + uint32x4_t p10 = vldrbq_u32(&s[tx + pixel_size_B]); + uint32x4_t p01 = vldrbq_u32(&s[tx + srcWidth]); + uint32x4_t p11 = vldrbq_u32(&s[tx + srcWidth + pixel_size_B]); + p00 = vmulq(p00, nx_frac); + p00 = vmlaq(p00, p10, x_frac); + p00 = vrshrq(p00, FRAC_BITS); + p01 = vmulq(p01, nx_frac); + p01 = vmlaq(p01, p11, x_frac); + p01 = vrshrq(p01, FRAC_BITS); + p00 = vmulq(p00, ny_frac); + p00 = vmlaq(p00, p01, y_frac); + p00 = vrshrq(p00, FRAC_BITS); + vstrbq_p_u32(d, p00, vctp32q(pixel_size_B)); + d += pixel_size_B; +#else + //interpolate and write out + for (int color = 0; color < pixel_size_B; + color++) // do pixel_size_B times for pixel_size_B colors + { + uint32_t p00, p01, p10, p11; + p00 = s[tx]; + p10 = s[tx + pixel_size_B]; + p01 = s[tx + srcWidth]; + p11 = s[tx + srcWidth + pixel_size_B]; + p00 = ((p00 * nx_frac) + (p10 * x_frac) + FRAC_VAL / 2) >> FRAC_BITS; // top line + p01 = ((p01 * nx_frac) + (p11 * x_frac) + FRAC_VAL / 2) >> FRAC_BITS; // bottom line + p00 = ((p00 * ny_frac) + (p01 * y_frac) + FRAC_VAL / 2) >> FRAC_BITS; //top + bottom + *d++ = (uint8_t)p00; // store new pixel + //ready next loop + tx++; + } +#endif + } // for x + } // for y + return 0; +} // resizeImage() + +#undef FRAC_BITS + +void calculate_crop_dims(uint32_t srcWidth, uint32_t srcHeight, + uint32_t dstWidth, uint32_t dstHeight, + uint32_t *cropWidth, uint32_t *cropHeight) { - /*first, trim the largest axis to match destination aspect ratio - calculate by fixing the smaller axis*/ - if (srcWidth > srcHeight) { - *cropWidth = (uint32_t)(dstWidth * srcHeight) / dstHeight; //cast in case int is small - *cropHeight = srcHeight; - } - else { - *cropHeight = (uint32_t)(dstHeight * srcWidth) / dstWidth; - *cropWidth = srcWidth; - } + //first, trim the largest axis to match destination aspect ratio + //calculate by fixing the smaller axis + if (srcWidth > srcHeight) + { + *cropWidth = (uint32_t)(dstWidth * srcHeight) / dstHeight; //cast in case int is small + *cropHeight = srcHeight; + } + + else + { + *cropHeight = (uint32_t)(dstHeight * srcWidth) / dstWidth; + *cropWidth = srcWidth; + } } -/** - \fn int crop_and_interpolate( uint8_t const *srcImage, - uint32_t srcWidth, - uint32_t srcHeight, - uint8_t *dstImage, - uint32_t dstWidth, - uint32_t dstHeight, - uint32_t bpp); - \brief Crop and interpolate the image to the given resolution. - \param[in] srcImage source image buffer address. - \param[in] srcWidth source image width. - \param[in] srcHeight source image height. - \param[in] dstImage destination image buffer address to save the cropped image. - \param[in] dstWidth destination image width. - \param[in] dstHeight destination image height. - \param[in] bpp number of bits per pixel. - \return return error status. zero for success negative value for error. -*/ -int crop_and_interpolate( uint8_t const *srcImage, - uint32_t srcWidth, - uint32_t srcHeight, - uint8_t *dstImage, - uint32_t dstWidth, - uint32_t dstHeight, + +int crop_and_interpolate( uint8_t const *srcImage, uint32_t srcWidth, + uint32_t srcHeight, uint8_t *dstImage, + uint32_t dstWidth, uint32_t dstHeight, uint32_t bpp) { - uint32_t cropWidth, cropHeight; - /*What are dimensions that maintain aspect ratio?*/ - calculate_crop_dims(srcWidth, srcHeight, dstWidth, dstHeight, &cropWidth, &cropHeight); - /*Now crop to that dimension*/ - int res = frame_crop( - (void *)srcImage, - srcWidth, - srcHeight, - (srcWidth - cropWidth) / 2, - (srcHeight - cropHeight) / 2, - (void *)dstImage, - cropWidth, - cropHeight, - bpp); - - if( res < 0 ) { return res; } - - /* Finally, interpolate down to desired dimensions, in place*/ - return resize_image(dstImage, cropWidth, cropHeight, dstImage, dstWidth, dstHeight, bpp/8); + uint32_t cropWidth, cropHeight; + + /*What are dimensions that maintain aspect ratio?*/ + calculate_crop_dims(srcWidth, srcHeight, dstWidth, dstHeight, &cropWidth, &cropHeight); + + /*Now crop to that dimension*/ + int res = frame_crop((void *)srcImage, srcWidth, srcHeight, + (srcWidth - cropWidth) / 2, + (srcHeight - cropHeight) / 2, + (void *)dstImage, cropWidth, + cropHeight, bpp); + + if( res < 0 ) + { + return res; + } + /* Finally, interpolate down to desired dimensions, in place*/ + return resize_image(dstImage, cropWidth, cropHeight, dstImage, dstWidth, dstHeight, bpp/8); } diff --git a/THREADX/samples/temperature.h b/THREADX/samples/temperature.h new file mode 100644 index 0000000..1e662e4 --- /dev/null +++ b/THREADX/samples/temperature.h @@ -0,0 +1,450 @@ +/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved. + * Use, distribution and modification of this code is permitted under the + * terms stated in the Alif Semiconductor Software License Agreement + * + * You should have received a copy of the Alif Semiconductor Software + * License Agreement with this file. If not, please write to: + * contact@alifsemi.com, or visit: https://alifsemi.com/license + */ + +#ifndef TEMPERATURE_H_ +#define TEMPERATURE_H_ + +#define MAX_TEMP_RANGE 402 + +/* Define a 2D array to store the ADC values and corresponding temperatures */ +const float tempData[][2] = { + {918, -40.0}, + {919, -39.6}, + {920, -39.2}, + {921, -38.8}, + {922, -38.4}, + {923, -38.0}, + {924, -37.6}, + {925, -37.2}, + {926, -36.8}, + {927, -36.4}, + {928, -36.0}, + {929, -35.6}, + {930, -35.2}, + {931, -34.8}, + {932, -34.4}, + {933, -34.0}, + {934, -33.6}, + {935, -33.2}, + {936, -32.8}, + {937, -32.4}, + {938, -32.0}, + {939, -31.6}, + {940, -31.2}, + {941, -30.8}, + {942, -30.4}, + {943, -30.0}, + {944, -29.8}, + {945, -29.7}, + {946, -29.5}, + {947, -29.3}, + {948, -29.2}, + {949, -29.0}, + {950, -28.8}, + {951, -28.7}, + {952, -28.5}, + {953, -28.3}, + {954, -28.2}, + {955, -28.0}, + {956, -27.8}, + {957, -27.7}, + {958, -27.5}, + {959, -27.3}, + {960, -27.2}, + {961, -27.0}, + {962, -26.8}, + {963, -26.7}, + {964, -26.5}, + {965, -26.3}, + {966, -26.2}, + {967, -26.0}, + {968, -25.8}, + {969, -25.7}, + {970, -25.5}, + {971, -25.3}, + {972, -25.2}, + {973, -25.0}, + {974, -24.8}, + {975, -24.7}, + {976, -24.5}, + {977, -24.3}, + {978, -24.2}, + {979, -24.0}, + {980, -23.8}, + {981, -23.7}, + {982, -23.5}, + {983, -23.3}, + {984, -23.2}, + {985, -23.0}, + {986, -22.8}, + {987, -22.7}, + {988, -22.5}, + {989, -22.3}, + {990, -22.2}, + {991, -22.0}, + {992, -21.8}, + {993, -21.7}, + {994, -21.5}, + {995, -21.3}, + {996, -21.2}, + {997, -21.0}, + {998, -20.8}, + {999, -20.7}, + {1000, -20.5}, + {1001, -20.3}, + {1002, -20.2}, + {1003, -20.0}, + {1004, -19.2}, + {1005, -18.5}, + {1006, -17.7}, + {1007, -16.9}, + {1008, -16.2}, + {1009, -15.4}, + {1010, -14.6}, + {1011, -13.8}, + {1012, -13.1}, + {1013, -12.3}, + {1014, -11.5}, + {1015, -10.8}, + {1016, -10.0}, + {1017, -9.4}, + {1018, -8.8}, + {1019, -8.1}, + {1020, -7.5}, + {1021, -6.9}, + {1022, -6.3}, + {1023, -5.6}, + {1024, -5.0}, + {1025, -4.4}, + {1026, -3.8}, + {1027, -3.1}, + {1028, -2.5}, + {1029, -1.9}, + {1030, -1.3}, + {1031, -0.6}, + {1032, 0.0}, + {1033, 0.7}, + {1034, 1.3}, + {1035, 2.0}, + {1036, 2.7}, + {1037, 3.3}, + {1038, 4.0}, + {1039, 4.7}, + {1040, 5.3}, + {1041, 6.0}, + {1042, 6.7}, + {1043, 7.3}, + {1044, 8.0}, + {1045, 8.7}, + {1046, 9.3}, + {1047, 10.0}, + {1048, 10.4}, + {1049, 10.9}, + {1050, 11.3}, + {1051, 11.7}, + {1052, 12.2}, + {1053, 12.6}, + {1054, 13.0}, + {1055, 13.5}, + {1056, 13.9}, + {1057, 14.3}, + {1058, 14.8}, + {1059, 15.2}, + {1060, 15.7}, + {1061, 16.1}, + {1062, 16.5}, + {1063, 17.0}, + {1064, 17.4}, + {1065, 17.8}, + {1066, 18.3}, + {1067, 18.7}, + {1068, 19.1}, + {1069, 19.6}, + {1070, 20.0}, + {1071, 20.2}, + {1072, 20.3}, + {1073, 20.5}, + {1074, 20.7}, + {1075, 20.9}, + {1076, 21.0}, + {1077, 21.2}, + {1078, 21.4}, + {1079, 21.6}, + {1080, 21.7}, + {1081, 21.9}, + {1082, 22.1}, + {1083, 22.2}, + {1084, 22.4}, + {1085, 22.6}, + {1086, 22.8}, + {1087, 22.9}, + {1088, 23.1}, + {1089, 23.3}, + {1090, 23.4}, + {1091, 23.6}, + {1092, 23.8}, + {1093, 24.0}, + {1094, 24.1}, + {1095, 24.3}, + {1096, 24.5}, + {1097, 24.7}, + {1098, 24.8}, + {1099, 25.0}, + {1100, 25.2}, + {1101, 25.3}, + {1102, 25.5}, + {1103, 25.7}, + {1104, 25.9}, + {1105, 26.0}, + {1106, 26.2}, + {1107, 26.4}, + {1108, 26.6}, + {1109, 26.7}, + {1110, 26.9}, + {1111, 27.1}, + {1112, 27.2}, + {1113, 27.4}, + {1114, 27.6}, + {1115, 27.8}, + {1116, 27.9}, + {1117, 28.1}, + {1118, 28.3}, + {1119, 28.4}, + {1120, 28.6}, + {1121, 28.8}, + {1122, 29.0}, + {1123, 29.1}, + {1124, 29.3}, + {1125, 29.5}, + {1126, 29.7}, + {1127, 29.8}, + {1128, 30.0}, + {1129, 30.3}, + {1130, 30.5}, + {1131, 30.8}, + {1132, 31.0}, + {1133, 31.3}, + {1134, 31.5}, + {1135, 31.8}, + {1136, 32.0}, + {1137, 32.3}, + {1138, 32.5}, + {1139, 32.8}, + {1140, 33.0}, + {1141, 33.3}, + {1142, 33.5}, + {1143, 33.8}, + {1144, 34.0}, + {1145, 34.3}, + {1146, 34.5}, + {1147, 34.8}, + {1148, 35.0}, + {1149, 35.3}, + {1150, 35.5}, + {1151, 35.8}, + {1152, 36.0}, + {1153, 36.3}, + {1154, 36.5}, + {1155, 36.8}, + {1156, 37.0}, + {1157, 37.3}, + {1158, 37.5}, + {1159, 37.8}, + {1160, 38.0}, + {1161, 38.3}, + {1162, 38.5}, + {1163, 38.8}, + {1164, 39.0}, + {1165, 39.3}, + {1166, 39.5}, + {1167, 39.8}, + {1168, 40.0}, + {1169, 40.5}, + {1170, 40.9}, + {1171, 41.4}, + {1172, 41.8}, + {1173, 42.3}, + {1174, 42.7}, + {1175, 43.2}, + {1176, 43.6}, + {1177, 44.1}, + {1178, 44.5}, + {1179, 45.0}, + {1180, 45.5}, + {1181, 45.9}, + {1182, 46.4}, + {1183, 46.8}, + {1184, 47.3}, + {1185, 47.7}, + {1186, 48.2}, + {1187, 48.6}, + {1188, 49.1}, + {1189, 49.5}, + {1190, 50.0}, + {1191, 50.2}, + {1192, 50.3}, + {1193, 50.5}, + {1194, 50.7}, + {1195, 50.9}, + {1196, 51.0}, + {1197, 51.2}, + {1198, 51.4}, + {1199, 51.6}, + {1200, 51.7}, + {1201, 51.9}, + {1202, 52.1}, + {1203, 52.2}, + {1204, 52.4}, + {1205, 52.6}, + {1206, 52.8}, + {1207, 52.9}, + {1208, 53.1}, + {1209, 53.3}, + {1210, 53.4}, + {1211, 53.6}, + {1212, 53.8}, + {1213, 54.0}, + {1214, 54.1}, + {1215, 54.3}, + {1216, 54.5}, + {1217, 54.7}, + {1218, 54.8}, + {1219, 55.0}, + {1220, 55.2}, + {1221, 55.3}, + {1222, 55.5}, + {1223, 55.7}, + {1224, 55.9}, + {1225, 56.0}, + {1226, 56.2}, + {1227, 56.4}, + {1228, 56.6}, + {1229, 56.7}, + {1230, 56.9}, + {1231, 57.1}, + {1232, 57.2}, + {1233, 57.4}, + {1234, 57.6}, + {1235, 57.8}, + {1236, 57.9}, + {1237, 58.1}, + {1238, 58.3}, + {1239, 58.4}, + {1240, 58.6}, + {1241, 58.8}, + {1242, 59.0}, + {1243, 59.1}, + {1244, 59.3}, + {1245, 59.5}, + {1246, 59.7}, + {1247, 59.8}, + {1248, 60.0}, + {1249, 60.3}, + {1250, 60.7}, + {1251, 61.0}, + {1252, 61.3}, + {1253, 61.7}, + {1254, 62.0}, + {1255, 62.3}, + {1256, 62.7}, + {1257, 63.0}, + {1258, 63.3}, + {1259, 63.7}, + {1260, 64.0}, + {1261, 64.3}, + {1262, 64.7}, + {1263, 65.0}, + {1264, 65.3}, + {1265, 65.7}, + {1266, 66.0}, + {1267, 66.3}, + {1268, 66.7}, + {1269, 67.0}, + {1270, 67.3}, + {1271, 67.7}, + {1272, 68.0}, + {1273, 68.3}, + {1274, 68.7}, + {1275, 69.0}, + {1276, 69.3}, + {1277, 69.7}, + {1278, 70.0}, + {1279, 70.4}, + {1280, 70.9}, + {1281, 71.3}, + {1282, 71.7}, + {1283, 72.2}, + {1284, 72.6}, + {1285, 73.0}, + {1286, 73.5}, + {1287, 73.9}, + {1288, 74.3}, + {1289, 74.8}, + {1290, 75.2}, + {1291, 75.7}, + {1292, 76.1}, + {1293, 76.5}, + {1294, 77.0}, + {1295, 77.4}, + {1296, 77.8}, + {1297, 78.3}, + {1298, 78.7}, + {1299, 79.1}, + {1300, 79.6}, + {1301, 80.0}, + {1302, 80.5}, + {1303, 81.1}, + {1304, 81.6}, + {1305, 82.1}, + {1306, 82.6}, + {1307, 83.2}, + {1308, 83.7}, + {1309, 84.2}, + {1310, 84.7}, + {1311, 85.3}, + {1312, 85.8}, + {1313, 86.3}, + {1314, 86.8}, + {1315, 87.4}, + {1316, 87.9}, + {1317, 88.4}, + {1318, 88.9}, + {1319, 89.5}, + {1320, 90.0} +}; + +/* + * @func : float get_temperature (uint32_t adc_value) + * @brief : Converts the digital value into a temperature reading + * @parameter[1] : adc_value : The digital value obtained from TSENS conversion + * @return : temperature + */ +float get_temperature (uint32_t adc_value) +{ + int i; + + /* check for temperature operating range */ + if (adc_value < tempData[0][0] || (adc_value > tempData[MAX_TEMP_RANGE][0])) + { + return -1; + } + + for (i = 0; i < sizeof(tempData) / sizeof(tempData[0]); i++) + { + /* check if value matches with tempdata */ + if (adc_value == tempData[i][0]) + { + break; + } + } + + return (tempData[i][1]); +} + +#endif /* TEMPERATURE_H_ */