From: richardbarry Date: Fri, 29 Apr 2011 10:31:01 +0000 (+0000) Subject: Update the SmartFusion SoftConsole source code to be the same as the IAR and Keil... X-Git-Tag: V7.0.1~23 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=ea65d3346d5631a30cbd8351842371027258f5d9;p=freertos Update the SmartFusion SoftConsole source code to be the same as the IAR and Keil versions. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1401 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/OLED/oled.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/OLED/oled.c index e6b9d8e5c..faa199d9a 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/OLED/oled.c +++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/OLED/oled.c @@ -318,7 +318,7 @@ void OLED_init(void ) */ void OLED_clear_display( oled_no_of_line LINES ) { - uint8_t i, j,start_line,end_line; + uint8_t i, j,start_line = 0,end_line = 0; uint8_t clear_8_columns[] = { OLED_DATA_CODE, 0x00, diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_flags.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_flags.c deleted file mode 100644 index 926a80dc2..000000000 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_flags.c +++ /dev/null @@ -1,1678 +0,0 @@ -/******************************************************************************* - * (c) Copyright 2009 Actel Corporation. All rights reserved. - * - * SVN $Revision: 2840 $ - * SVN $Date: 2010-07-20 17:00:32 +0100 (Tue, 20 Jul 2010) $ - */ -#include "mss_ace.h" -#include "mss_ace_configurator.h" -#include "../../CMSIS/a2fxxxm3.h" -#include "../../CMSIS/mss_assert.h" -#include "../../drivers_config/mss_ace/ace_handles.h" -#include "../../drivers_config/mss_ace/ace_config.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_FULL_FLAG_NAME_LENGTH (MAX_CHANNEL_NAME_LENGTH + MAX_FLAG_NAME_LENGTH + 1) - -/*-------------------------------------------------------------------------*//** - * Number of flag types supported. - * the supported flag types are: - * - BASIC_THRESHOLD_OVER - * - BASIC_THRESHOLD_UNDER - * - STATE_FILTERED_OVER - * - STATE_FILTERED_UNDER - * - DUAL_HYSTERESIS_OVER - * - DUAL_HYSTERESIS_UNDER - * - IPMI_HYSTERESIS_OVER - * - IPMI_HYSTERESIS_UNDER - */ -#define NB_OF_FLAG_TYPES 8 - -/*-------------------------------------------------------------------------*//** - * - */ -#define THRESHOLD_FLAG0 0u -#define THRESHOLD_FLAG1 1u -#define THRESHOLD_FLAG2 2u -#define THRESHOLD_FLAG3 3u -#define THRESHOLD_FLAG4 4u -#define THRESHOLD_FLAG5 5u -#define THRESHOLD_FLAG6 6u -#define THRESHOLD_FLAG7 7u -#define THRESHOLD_FLAG8 8u -#define THRESHOLD_FLAG9 9u -#define THRESHOLD_FLAG10 10u -#define THRESHOLD_FLAG11 11u -#define THRESHOLD_FLAG12 12u -#define THRESHOLD_FLAG13 13u -#define THRESHOLD_FLAG14 14u -#define THRESHOLD_FLAG15 15u -#define THRESHOLD_FLAG16 16u -#define THRESHOLD_FLAG17 17u -#define THRESHOLD_FLAG18 18u -#define THRESHOLD_FLAG19 19u -#define THRESHOLD_FLAG20 20u -#define THRESHOLD_FLAG21 21u -#define THRESHOLD_FLAG22 22u -#define THRESHOLD_FLAG23 23u -#define THRESHOLD_FLAG24 24u -#define THRESHOLD_FLAG25 25u -#define THRESHOLD_FLAG26 26u -#define THRESHOLD_FLAG27 27u -#define THRESHOLD_FLAG28 28u -#define THRESHOLD_FLAG29 29u -#define THRESHOLD_FLAG30 30u -#define THRESHOLD_FLAG31 31u -#define NB_OF_THRESHOLD_IRQ 32u - -/*-------------------------------------------------------------------------*//** - * - */ -void ace_init_flags( void ); - -/*-------------------------------------------------------------------------*//** - * Flag interrupots routines function prototypes - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag0_IRQHandler( void ); -#else -void ACE_PPE_Flag0_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag1_IRQHandler( void ); -#else -void ACE_PPE_Flag1_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag2_IRQHandler( void ); -#else -void ACE_PPE_Flag2_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag3_IRQHandler( void ); -#else -void ACE_PPE_Flag3_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag4_IRQHandler( void ); -#else -void ACE_PPE_Flag4_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag5_IRQHandler( void ); -#else -void ACE_PPE_Flag5_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag6_IRQHandler( void ); -#else -void ACE_PPE_Flag6_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag7_IRQHandler( void ); -#else -void ACE_PPE_Flag7_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag8_IRQHandler( void ); -#else -void ACE_PPE_Flag8_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag9_IRQHandler( void ); -#else -void ACE_PPE_Flag9_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag10_IRQHandler( void ); -#else -void ACE_PPE_Flag10_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag11_IRQHandler( void ); -#else -void ACE_PPE_Flag11_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag12_IRQHandler( void ); -#else -void ACE_PPE_Flag12_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag13_IRQHandler( void ); -#else -void ACE_PPE_Flag13_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag14_IRQHandler( void ); -#else -void ACE_PPE_Flag14_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag15_IRQHandler( void ); -#else -void ACE_PPE_Flag15_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag16_IRQHandler( void ); -#else -void ACE_PPE_Flag16_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag17_IRQHandler( void ); -#else -void ACE_PPE_Flag17_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag18_IRQHandler( void ); -#else -void ACE_PPE_Flag18_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag19_IRQHandler( void ); -#else -void ACE_PPE_Flag19_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag20_IRQHandler( void ); -#else -void ACE_PPE_Flag20_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag21_IRQHandler( void ); -#else -void ACE_PPE_Flag21_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag22_IRQHandler( void ); -#else -void ACE_PPE_Flag22_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag23_IRQHandler( void ); -#else -void ACE_PPE_Flag23_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag24_IRQHandler( void ); -#else -void ACE_PPE_Flag24_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag25_IRQHandler( void ); -#else -void ACE_PPE_Flag25_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag26_IRQHandler( void ); -#else -void ACE_PPE_Flag26_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag27_IRQHandler( void ); -#else -void ACE_PPE_Flag27_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag28_IRQHandler( void ); -#else -void ACE_PPE_Flag28_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag29_IRQHandler( void ); -#else -void ACE_PPE_Flag29_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag30_IRQHandler( void ); -#else -void ACE_PPE_Flag30_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag31_IRQHandler( void ); -#else -void ACE_PPE_Flag31_IRQHandler( void ); -#endif - -/*-------------------------------------------------------------------------*//** - * - */ -#if (ACE_NB_OF_PPE_FLAGS > 0) -extern ppe_flag_desc_t g_ppe_flags_desc_table[ACE_NB_OF_PPE_FLAGS]; -#endif - -extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS]; - -extern ace_adc_config_t g_ace_adc_config[ACE_NB_OF_ADC]; - -#if (ACE_NB_OF_PPE_FLAGS > 0) -/*-------------------------------------------------------------------------*//** - Lookup table indexed on flag_id_t of the index of the flag's descriptor index - in the flag descriptors table g_ppe_flags_desc_table[] - */ -static ace_flag_handle_t g_ppe_flag_handles_lut[NB_OF_PPE_FLAGS]; - -/*-------------------------------------------------------------------------*//** - * - */ -static flag_isr_t g_ppe_flags_isr_lut[NB_OF_PPE_FLAGS]; - -/*-------------------------------------------------------------------------*//** - * - */ -static global_flag_isr_t g_ppe_global_flags_isr; - -/*-------------------------------------------------------------------------*//** - * - */ -static channel_flag_isr_t g_ppe_channel_flags_isr_lut[ACE_NB_OF_INPUT_CHANNELS]; -#endif - -/*-------------------------------------------------------------------------*//** - Intialise the ACE driver's internal data structures used by flag control - functions. - */ -void ace_init_flags( void ) -{ - /* Ensure the generated ACE configuration files are consistent. */ - ASSERT(NB_OF_ACE_FLAG_HANDLES == ACE_NB_OF_PPE_FLAGS); - -#if (ACE_NB_OF_PPE_FLAGS > 0) - { - uint8_t flag_idx; - uint8_t channel_idx; - - for ( flag_idx = 0u; flag_idx < (uint8_t)NB_OF_PPE_FLAGS; ++flag_idx ) - { - g_ppe_flags_isr_lut[flag_idx] = 0; - g_ppe_flag_handles_lut[flag_idx] = INVALID_FLAG_HANDLE; - } - - for ( flag_idx = 0u; flag_idx < (uint8_t)ACE_NB_OF_PPE_FLAGS; ++flag_idx ) - { - ASSERT( g_ppe_flags_desc_table[flag_idx].flag_id < NB_OF_PPE_FLAGS ); - g_ppe_flag_handles_lut[g_ppe_flags_desc_table[flag_idx].flag_id] = (ace_flag_handle_t)flag_idx; - } - - for ( channel_idx = 0u; channel_idx < (uint8_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx ) - { - g_ppe_channel_flags_isr_lut[channel_idx] = 0; - } - - g_ppe_global_flags_isr = 0u; - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -uint32_t ACE_is_hysteresis_flag( ace_flag_handle_t flag_handle ) -{ - uint32_t hysteresis = 0u; - -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( g_ppe_flags_desc_table[flag_handle].flag_type >= DUAL_HYSTERESIS_OVER ) - { - hysteresis = 1u; - } -#endif - return hysteresis; -} - -/*-------------------------------------------------------------------------*//** - * - */ -uint32_t ACE_is_under_flag -( - ace_flag_handle_t flag_handle -) -{ - uint32_t is_under = 0; - -#if (ACE_NB_OF_PPE_FLAGS > 0) - const uint32_t flag_type_lut[NB_OF_FLAG_TYPES] = - { - 0, /* BASIC_THRESHOLD_OVER */ - 1, /* BASIC_THRESHOLD_UNDER */ - 0, /* STATE_FILTERED_OVER */ - 1, /* STATE_FILTERED_UNDER */ - 0, /* DUAL_HYSTERESIS_OVER */ - 1, /* DUAL_HYSTERESIS_UNDER */ - 0, /* IPMI_HYSTERESIS_OVER */ - 1, /* IPMI_HYSTERESIS_UNDER */ - }; - - ASSERT(flag_handle < ACE_NB_OF_PPE_FLAGS); - if (flag_handle < ACE_NB_OF_PPE_FLAGS) - { - uint8_t flag_type; - flag_type = g_ppe_flags_desc_table[flag_handle].flag_type; - ASSERT(flag_type < NB_OF_FLAG_TYPES); - if (flag_type < NB_OF_FLAG_TYPES) - { - is_under = flag_type_lut[flag_type]; - } - } -#endif - return is_under; -} - -/*-------------------------------------------------------------------------*//** - Mask of the threshold value bits within a PPE RAM meory location holding the - threshold value for a flag. - */ -#define PPE_RAM_THRESHOLD_MASK 0x0000FFFFuL - -/*-------------------------------------------------------------------------*//** - * TODO: handle IPMI hysteresis flags - */ -void ACE_set_flag_threshold -( - ace_flag_handle_t flag_handle, - uint16_t new_threshold -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - uint16_t ppe_offset; - - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) - { - - ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; - - if ( ACE_is_hysteresis_flag( flag_handle ) == 0u ) - { - ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & (uint32_t)~PPE_RAM_THRESHOLD_MASK) + new_threshold; - } - else - { - uint16_t high_threshold; - uint16_t low_threshold; - ace_channel_handle_t channel_handle; - uint16_t hysteresis; - uint32_t adc_id; - uint16_t adc_resolution; - - high_threshold = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset] & PPE_RAM_THRESHOLD_MASK); - low_threshold = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset + 1u] & PPE_RAM_THRESHOLD_MASK); - ASSERT(high_threshold > low_threshold); - hysteresis = (uint16_t)(high_threshold - low_threshold) / 2u; - - channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle; - adc_id = (uint32_t)(g_ace_channel_desc_table[channel_handle].signal_id) >> 4u; - ASSERT( adc_id < (uint32_t)ACE_NB_OF_ADC ); - - if ( adc_id < (uint32_t)ACE_NB_OF_ADC ) - { - adc_resolution = g_ace_adc_config[adc_id].adc_resolution - 1u; - - high_threshold = new_threshold + hysteresis; - if ( high_threshold > adc_resolution ) - { - high_threshold = adc_resolution; - } - - if ( hysteresis > new_threshold ) - { - low_threshold = 1u; - } - else - { - low_threshold = new_threshold - hysteresis; - } - - ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + high_threshold; - ACE->PPE_RAM_DATA[ppe_offset + 1u] = (ACE->PPE_RAM_DATA[ppe_offset + 1u] & (uint32_t)~PPE_RAM_THRESHOLD_MASK) + low_threshold; - } - } - } -#endif -} - - -/*-------------------------------------------------------------------------*//** - * - */ -#define FLAG_OVER_UNDER_MASK 0x01u -#define FLAG_OVER 0x00u -#define FLAF_UNDER 0x01 - -void ACE_set_flag_assertion -( - ace_flag_handle_t flag_handle, - uint16_t assertion_value -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - uint16_t ppe_offset; - - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) - { - if (ACE_is_hysteresis_flag(flag_handle)) - { - uint8_t flag_direction; - flag_direction = g_ppe_flags_desc_table[flag_handle].flag_type & FLAG_OVER_UNDER_MASK; - - if ( FLAG_OVER == flag_direction ) - { - ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; - } - else - { - ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset + 1u; - } - } - else - { - ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; - } - ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + assertion_value; - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_set_flag_deassertion -( - ace_flag_handle_t flag_handle, - uint16_t assertion_value -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - uint16_t ppe_offset; - - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - ASSERT(ACE_is_hysteresis_flag(flag_handle)); - - if ((flag_handle < NB_OF_ACE_FLAG_HANDLES) && (ACE_is_hysteresis_flag(flag_handle))) - { - uint8_t flag_direction; - flag_direction = g_ppe_flags_desc_table[flag_handle].flag_type & FLAG_OVER_UNDER_MASK; - - if ( FLAG_OVER == flag_direction ) - { - ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset + 1u; - } - else - { - ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; - } - - ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + assertion_value; - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void -ACE_set_flag_hysteresis -( - ace_flag_handle_t flag_handle, - uint16_t adc_hysteresis -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - uint16_t ppe_offset; - uint32_t high_threshold; - uint32_t low_threshold; - uint32_t nominal_threshold; - uint16_t adc_resolution; - uint32_t adc_id; - - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - ASSERT(ACE_is_hysteresis_flag(flag_handle)); - - if ( ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) && ( ACE_is_hysteresis_flag( flag_handle ) ) ) - { - ace_channel_handle_t channel_handle; - - ppe_offset = g_ppe_flags_desc_table[flag_handle].threshold_ppe_offset; - - high_threshold = ACE->PPE_RAM_DATA[ppe_offset] & PPE_RAM_THRESHOLD_MASK; - low_threshold = ACE->PPE_RAM_DATA[ppe_offset + 1u] & PPE_RAM_THRESHOLD_MASK; - ASSERT(high_threshold > low_threshold); - nominal_threshold = (low_threshold + ((high_threshold - low_threshold) / 2u)); - - channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle; - adc_id = (uint32_t)((uint32_t)g_ace_channel_desc_table[channel_handle].signal_id >> 4u); - ASSERT( adc_id < (uint32_t)ACE_NB_OF_ADC ); - - if ( adc_id < (uint32_t)ACE_NB_OF_ADC ) - { - adc_resolution = g_ace_adc_config[adc_id].adc_resolution; - - high_threshold = nominal_threshold + adc_hysteresis; - if ( high_threshold > adc_resolution ) - { - high_threshold = (uint32_t)adc_resolution - 1u; - } - - if ( adc_hysteresis > nominal_threshold ) - { - low_threshold = 1u; - } - else - { - low_threshold = nominal_threshold - adc_hysteresis; - } - - ACE->PPE_RAM_DATA[ppe_offset] = (ACE->PPE_RAM_DATA[ppe_offset] & ~PPE_RAM_THRESHOLD_MASK) + high_threshold; - ACE->PPE_RAM_DATA[ppe_offset + 1u] = (ACE->PPE_RAM_DATA[ppe_offset + 1u] & ~PPE_RAM_THRESHOLD_MASK) + low_threshold; - } - } -#endif -} - - -/*-------------------------------------------------------------------------*//** - * - */ -void -ACE_set_channel_hysteresis -( - ace_channel_handle_t channel_handle, - uint16_t adc_hysteresis -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - ace_flag_handle_t flag_handle; - - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); - - if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) - { - uint16_t i; - - for( i = 0u; i < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++i ) - { - flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[i]; - ACE_set_flag_hysteresis( flag_handle, adc_hysteresis ); - } - } -#endif -} - -/*============================================================================== - * - */ - -/*-------------------------------------------------------------------------*//** - Masking a flag_id with FLAG_BIT_OFFSET_MASK results in the offset of the - flag bit within a PPE__FLAGSn register. - */ -#define FLAG_BIT_OFFSET_MASK 0x0000001FuL - -/*-------------------------------------------------------------------------*//** - Shifting right a flag_id by FLAG_PPE_REG_SHIFT results in identifying the - PPE_FLAGSn or PPE_SFFLAGS the flags belongs to. - */ -#define FLAG_PPE_REG_SHIFT 5u - -/*-------------------------------------------------------------------------*//** - There is a set of 5 PPE flag registers to control and report status of the PPE - flags resulting in the PPE flags being grouped into 5 separate flag groups at - the register level. Each register provides status or control for 32 flags. - */ -#define NB_OF_FLAG_GROUPS 5u -#define NB_OF_FLAGS_PER_GROUP 32u - -#if (ACE_NB_OF_PPE_FLAGS > 0) -/*-------------------------------------------------------------------------*//** - Lookup table of the address PPE_FLAGSn registers for fast reading of PPE - status. - */ -static volatile uint32_t * const g_ppe_flags_regs_lut[NB_OF_FLAG_GROUPS] = -{ - &ACE->PPE_FLAGS0, - &ACE->PPE_FLAGS1, - &ACE->PPE_FLAGS2, - &ACE->PPE_FLAGS3, - &ACE->PPE_SFFLAGS -}; - -/*-------------------------------------------------------------------------*//** - Lookup table of the address of the PPE flags interrupt enable registers. - */ -static uint32_t volatile * const flags_irq_enable_regs_lut[NB_OF_FLAG_GROUPS] = -{ - &ACE->PPE_FLAGS0_IRQ_EN, - &ACE->PPE_FLAGS1_IRQ_EN, - &ACE->PPE_FLAGS2_IRQ_EN, - &ACE->PPE_FLAGS3_IRQ_EN, - &ACE->PPE_SFFLAGS_IRQ_EN -}; - -/*-------------------------------------------------------------------------*//** - Lookup table of the address of the PPE flags interrupt status registers. - */ -static uint32_t volatile const * const flags_irq_status_regs_lut[NB_OF_FLAG_GROUPS] = -{ - &ACE->PPE_FLAGS0_IRQ, - &ACE->PPE_FLAGS1_IRQ, - &ACE->PPE_FLAGS2_IRQ, - &ACE->PPE_FLAGS3_IRQ, - &ACE->PPE_SFFLAGS_IRQ -}; - -/*-------------------------------------------------------------------------*//** - Lookup table of the address of the PPE flags interrupt clearing registers. - */ -static uint32_t volatile * const flags_irq_clear_regs_lut[NB_OF_FLAG_GROUPS] = -{ - &ACE->PPE_FLAGS0_IRQ_CLR, - &ACE->PPE_FLAGS1_IRQ_CLR, - &ACE->PPE_FLAGS2_IRQ_CLR, - &ACE->PPE_FLAGS3_IRQ_CLR, - &ACE->PPE_SFFLAGS_IRQ_CLR -}; - -/*-------------------------------------------------------------------------*//** - * - */ -static const IRQn_Type threshold_irqn_lut[NB_OF_THRESHOLD_IRQ] = -{ - ACE_PPE_Flag0_IRQn, - ACE_PPE_Flag1_IRQn, - ACE_PPE_Flag2_IRQn, - ACE_PPE_Flag3_IRQn, - ACE_PPE_Flag4_IRQn, - ACE_PPE_Flag5_IRQn, - ACE_PPE_Flag6_IRQn, - ACE_PPE_Flag7_IRQn, - ACE_PPE_Flag8_IRQn, - ACE_PPE_Flag9_IRQn, - ACE_PPE_Flag10_IRQn, - ACE_PPE_Flag11_IRQn, - ACE_PPE_Flag12_IRQn, - ACE_PPE_Flag13_IRQn, - ACE_PPE_Flag14_IRQn, - ACE_PPE_Flag15_IRQn, - ACE_PPE_Flag16_IRQn, - ACE_PPE_Flag17_IRQn, - ACE_PPE_Flag18_IRQn, - ACE_PPE_Flag19_IRQn, - ACE_PPE_Flag20_IRQn, - ACE_PPE_Flag21_IRQn, - ACE_PPE_Flag22_IRQn, - ACE_PPE_Flag23_IRQn, - ACE_PPE_Flag24_IRQn, - ACE_PPE_Flag25_IRQn, - ACE_PPE_Flag26_IRQn, - ACE_PPE_Flag27_IRQn, - ACE_PPE_Flag28_IRQn, - ACE_PPE_Flag29_IRQn, - ACE_PPE_Flag30_IRQn, - ACE_PPE_Flag31_IRQn -}; -#endif - -/*-------------------------------------------------------------------------*//** - */ -ace_flag_handle_t -ACE_get_flag_handle -( - const uint8_t * p_sz_full_flag_name -) -{ - ace_flag_handle_t flag_handle = INVALID_FLAG_HANDLE; -#if (ACE_NB_OF_PPE_FLAGS > 0) - ace_flag_handle_t flag_idx; - - for ( flag_idx = (ace_flag_handle_t)0; flag_idx < NB_OF_ACE_FLAG_HANDLES; ++flag_idx ) - { - if ( g_ppe_flags_desc_table[flag_idx].p_sz_flag_name != 0 ) - { - int32_t diff; - diff = strncmp( (const char *)p_sz_full_flag_name, (const char *)g_ppe_flags_desc_table[flag_idx].p_sz_flag_name, (size_t)MAX_FULL_FLAG_NAME_LENGTH ); - if ( 0 == diff ) - { - /* flag name found. */ - flag_handle = (ace_flag_handle_t)flag_idx; - break; - } - } - } -#endif - return flag_handle; -} - -/*-------------------------------------------------------------------------*//** - */ -int32_t -ACE_get_flag_status -( - ace_flag_handle_t flag_handle -) -{ - int32_t flag_state = UNKNOWN_FLAG; -#if (ACE_NB_OF_PPE_FLAGS > 0) - ppe_flag_id_t flag_id; - - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) - { - uint32_t flag_bit_offset; - uint32_t ppe_flag_group; - uint32_t flag_id_mask; - uint32_t flag_status; - - flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; - - if ( flag_id < NB_OF_PPE_FLAGS ) - { - flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK); - ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT); - flag_id_mask = 1uL << flag_bit_offset; - flag_status = *(g_ppe_flags_regs_lut[ppe_flag_group]) & flag_id_mask; - if ( flag_status > 0u ) - { - flag_state = FLAG_ASSERTED; - } - else - { - flag_state = FLAG_NOT_ASSERTED; - } - } - - } -#endif - return flag_state; -} - - -/*-------------------------------------------------------------------------*//** - */ -const uint8_t * -ACE_get_flag_name -( - ace_flag_handle_t flag_handle -) -{ - const uint8_t * psz_flag_name = 0; -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) - { - psz_flag_name = g_ppe_flags_desc_table[flag_handle].p_sz_flag_name; - } -#endif - return psz_flag_name; -} - -/*-------------------------------------------------------------------------*//** - */ -ace_channel_handle_t -ACE_get_flag_channel -( - ace_flag_handle_t flag_handle -) -{ - ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE; -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) - { - channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle; - } -#endif - return channel_handle; -} - -/*-------------------------------------------------------------------------*//** - */ -uint32_t -ACE_get_channel_flag_count -( - ace_channel_handle_t channel_handle -) -{ - uint32_t flag_count = 0; -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( channel_handle < ACE_NB_OF_INPUT_CHANNELS ); - if (channel_handle < ACE_NB_OF_INPUT_CHANNELS) - { - flag_count = g_ace_channel_desc_table[channel_handle].nb_of_flags; - } -#endif - return flag_count; -} - -/*-------------------------------------------------------------------------*//** - - */ -ace_flag_handle_t -ACE_get_channel_first_flag -( - ace_channel_handle_t channel_handle, - uint16_t * iterator -) -{ - ace_flag_handle_t flag_handle = INVALID_FLAG_HANDLE; -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES); - - *iterator = 0u; - - if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES) - { - if ( g_ace_channel_desc_table[channel_handle].nb_of_flags > 0u ) - { - flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[*iterator]; - } - } -#endif - return flag_handle; -} - -/*-------------------------------------------------------------------------*//** - - */ -ace_flag_handle_t -ACE_get_channel_next_flag -( - ace_channel_handle_t channel_handle, - uint16_t * iterator -) -{ - ace_flag_handle_t flag_handle = INVALID_FLAG_HANDLE; -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES); - - if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES) - { - ++(*iterator); - - if ( *iterator >= g_ace_channel_desc_table[channel_handle].nb_of_flags ) - { - *iterator = 0u; - } - - if ( g_ace_channel_desc_table[channel_handle].nb_of_flags > 0u ) - { - flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[*iterator]; - } - } -#endif - return flag_handle; -} - - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_enable_channel_flags_irq -( - ace_channel_handle_t channel_handle -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - uint32_t flag_idx; - ace_flag_handle_t flag_handle; - - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); - - if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) - { - for ( flag_idx = 0u; flag_idx < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++flag_idx ) - { - flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[flag_idx]; - ACE_enable_flag_irq( flag_handle ); - } - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_disable_channel_flags_irq -( - ace_channel_handle_t channel_handle -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - uint32_t flag_idx; - ace_flag_handle_t flag_handle; - - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); - - if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) - { - for ( flag_idx = 0u; flag_idx < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++flag_idx ) - { - flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[flag_idx]; - ACE_disable_flag_irq( flag_handle ); - } - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_clear_channel_flags_irq -( - ace_channel_handle_t channel_handle -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - uint32_t flag_idx; - ace_flag_handle_t flag_handle; - - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); - - if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) - { - for ( flag_idx = 0u; flag_idx < g_ace_channel_desc_table[channel_handle].nb_of_flags; ++flag_idx ) - { - flag_handle = (ace_flag_handle_t)g_ace_channel_desc_table[channel_handle].p_flags_array[flag_idx]; - ACE_clear_flag_irq( flag_handle ); - } - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_enable_flag_irq -( - ace_flag_handle_t flag_handle -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) - { - ppe_flag_id_t flag_id; - uint32_t flag_bit_offset; - uint32_t ppe_flag_group; - uint32_t flag_id_mask; - - flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; - - ASSERT( flag_id < NB_OF_PPE_FLAGS ); - - flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK); - ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT); - flag_id_mask = 1uL << flag_bit_offset; - - ASSERT( ppe_flag_group < NB_OF_FLAG_GROUPS ); - - if ( ppe_flag_group < NB_OF_FLAG_GROUPS ) - { - *(flags_irq_enable_regs_lut[ppe_flag_group]) |= flag_id_mask; - } - - NVIC_EnableIRQ( threshold_irqn_lut[flag_bit_offset] ); - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_disable_flag_irq -( - ace_flag_handle_t flag_handle -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) - { - ppe_flag_id_t flag_id; - uint32_t flag_bit_offset; - uint32_t ppe_flag_group; - uint32_t flag_id_mask; - - flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; - - ASSERT( flag_id < NB_OF_PPE_FLAGS ); - - flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK); - ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT); - flag_id_mask = 1uL << flag_bit_offset; - - ASSERT( ppe_flag_group < NB_OF_FLAG_GROUPS ); - - if ( ppe_flag_group < NB_OF_FLAG_GROUPS ) - { - *(flags_irq_enable_regs_lut[ppe_flag_group]) &= (uint32_t)~flag_id_mask; - } - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_clear_flag_irq -( - ace_flag_handle_t flag_handle -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) - { - ppe_flag_id_t flag_id; - uint32_t flag_bit_offset; - uint32_t ppe_flag_group; - uint32_t flag_id_mask; - - flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; - - ASSERT( flag_id < NB_OF_PPE_FLAGS ); - - flag_bit_offset = ((uint32_t)flag_id & FLAG_BIT_OFFSET_MASK); - ppe_flag_group = ((uint32_t)flag_id >> FLAG_PPE_REG_SHIFT); - flag_id_mask = 1uL << flag_bit_offset; - - ASSERT( ppe_flag_group < NB_OF_FLAG_GROUPS ); - - if ( ppe_flag_group < NB_OF_FLAG_GROUPS ) - { - *(flags_irq_clear_regs_lut[ppe_flag_group]) |= flag_id_mask; - } - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_register_flag_isr -( - ace_flag_handle_t flag_handle, - flag_isr_t flag_isr -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - ppe_flag_id_t flag_id; - - ASSERT( flag_handle < NB_OF_ACE_FLAG_HANDLES ); - - if ( flag_handle < NB_OF_ACE_FLAG_HANDLES ) - { - flag_id = g_ppe_flags_desc_table[flag_handle].flag_id; - - ASSERT( flag_id < NB_OF_PPE_FLAGS ); - - if ( flag_id < NB_OF_PPE_FLAGS ) - { - g_ppe_flags_isr_lut[flag_id] = flag_isr; - } - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_register_channel_flags_isr -( - ace_channel_handle_t channel_handle, - channel_flag_isr_t channel_flag_isr -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); - - if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) - { - g_ppe_channel_flags_isr_lut[channel_handle] = channel_flag_isr; - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_register_global_flags_isr -( - global_flag_isr_t global_flag_isr -) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - g_ppe_global_flags_isr = global_flag_isr; -#endif -} - - -/*============================================================================== - * - */ - -/*-------------------------------------------------------------------------*//** - * Actual PPE flag interrupt service routines: - */ - -static void process_flag_irq( uint8_t threshold_flag_id ) -{ -#if (ACE_NB_OF_PPE_FLAGS > 0) - uint8_t flag_group; - uint32_t threshold_flag_mask; - ppe_flag_id_t flag_id; - uint32_t irq_enable_reg; - uint32_t irq_status_reg; - uint32_t irq_active; - - threshold_flag_mask = 1uL << threshold_flag_id; - - - for ( flag_group = 0u; flag_group < NB_OF_FLAG_GROUPS; ++flag_group ) - { - irq_enable_reg = *flags_irq_enable_regs_lut[flag_group]; - irq_status_reg = *flags_irq_status_regs_lut[flag_group]; - irq_active = threshold_flag_mask & irq_enable_reg & irq_status_reg; - - if ( irq_active ) - { - ace_flag_handle_t flag_handle; - ace_channel_handle_t channel_handle; - - flag_id = (ppe_flag_id_t)((flag_group * NB_OF_FLAGS_PER_GROUP) + threshold_flag_id); - flag_handle = g_ppe_flag_handles_lut[flag_id]; - - /* Call individual flag handler */ - if ( g_ppe_flags_isr_lut[flag_id] != 0 ) - { - g_ppe_flags_isr_lut[flag_id]( flag_handle ); - } - - /* Call the channel flag handler. */ - channel_handle = g_ppe_flags_desc_table[flag_handle].channel_handle; - if ( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ) - { - if ( g_ppe_channel_flags_isr_lut[channel_handle] != 0 ) - { - g_ppe_channel_flags_isr_lut[channel_handle]( flag_handle ); - } - } - - /* Call the global flag handler. */ - if ( g_ppe_global_flags_isr != 0 ) - { - g_ppe_global_flags_isr( flag_handle, channel_handle ); - } - - /* Clear the flag interrupt */ - *flags_irq_clear_regs_lut[flag_group] |= threshold_flag_mask; - } - } -#endif -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag0_IRQHandler( void ) -#else -void ACE_PPE_Flag0_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG0 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag0_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag1_IRQHandler( void ) -#else -void ACE_PPE_Flag1_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG1 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag1_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag2_IRQHandler( void ) -#else -void ACE_PPE_Flag2_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG2 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag2_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag3_IRQHandler( void ) -#else -void ACE_PPE_Flag3_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG3 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag3_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag4_IRQHandler( void ) -#else -void ACE_PPE_Flag4_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG4 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag4_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag5_IRQHandler( void ) -#else -void ACE_PPE_Flag5_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG5 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag5_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag6_IRQHandler( void ) -#else -void ACE_PPE_Flag6_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG6 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag6_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag7_IRQHandler( void ) -#else -void ACE_PPE_Flag7_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG7 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag7_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag8_IRQHandler( void ) -#else -void ACE_PPE_Flag8_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG8 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag8_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag9_IRQHandler( void ) -#else -void ACE_PPE_Flag9_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG9 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag9_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag10_IRQHandler( void ) -#else -void ACE_PPE_Flag10_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG10 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag10_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag11_IRQHandler( void ) -#else -void ACE_PPE_Flag11_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG11 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag11_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag12_IRQHandler( void ) -#else -void ACE_PPE_Flag12_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG12 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag12_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag13_IRQHandler( void ) -#else -void ACE_PPE_Flag13_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG13 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag13_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag14_IRQHandler( void ) -#else -void ACE_PPE_Flag14_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG14 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag14_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag15_IRQHandler( void ) -#else -void ACE_PPE_Flag15_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG15 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag15_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag16_IRQHandler( void ) -#else -void ACE_PPE_Flag16_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG16 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag16_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag17_IRQHandler( void ) -#else -void ACE_PPE_Flag17_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG17 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag17_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag18_IRQHandler( void ) -#else -void ACE_PPE_Flag18_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG18 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag18_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag19_IRQHandler( void ) -#else -void ACE_PPE_Flag19_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG19 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag19_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag20_IRQHandler( void ) -#else -void ACE_PPE_Flag20_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG20 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag20_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag21_IRQHandler( void ) -#else -void ACE_PPE_Flag21_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG21 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag21_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag22_IRQHandler( void ) -#else -void ACE_PPE_Flag22_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG22 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag22_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag23_IRQHandler( void ) -#else -void ACE_PPE_Flag23_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG23 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag23_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag24_IRQHandler( void ) -#else -void ACE_PPE_Flag24_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG24 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag24_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag25_IRQHandler( void ) -#else -void ACE_PPE_Flag25_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG25 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag25_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag26_IRQHandler( void ) -#else -void ACE_PPE_Flag26_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG26 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag26_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag27_IRQHandler( void ) -#else -void ACE_PPE_Flag27_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG27 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag27_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag28_IRQHandler( void ) -#else -void ACE_PPE_Flag28_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG28 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag28_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag29_IRQHandler( void ) -#else -void ACE_PPE_Flag29_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG29 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag29_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag30_IRQHandler( void ) -#else -void ACE_PPE_Flag30_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG30 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag30_IRQn ); -} - -/*-------------------------------------------------------------------------*//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void ACE_PPE_Flag31_IRQHandler( void ) -#else -void ACE_PPE_Flag31_IRQHandler( void ) -#endif -{ - process_flag_irq( THRESHOLD_FLAG31 ); - NVIC_ClearPendingIRQ( ACE_PPE_Flag31_IRQn ); -} - -#ifdef __cplusplus -} -#endif - diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_sse.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_sse.c deleted file mode 100644 index eefb06b18..000000000 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_sse.c +++ /dev/null @@ -1,306 +0,0 @@ -/******************************************************************************* - * (c) Copyright 2009 Actel Corporation. All rights reserved. - * - * SVN $Revision: 2905 $ - * SVN $Date: 2010-08-20 14:03:28 +0100 (Fri, 20 Aug 2010) $ - */ -#include "mss_ace.h" -#include "mss_ace_configurator.h" -#include "../../drivers_config/mss_ace/ace_handles.h" -#include "../../drivers_config/mss_ace/ace_config.h" - -#include "../../CMSIS/a2fxxxm3.h" -#include "../../CMSIS/mss_assert.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define SSE_START 1uL -#define SSE_STOP 0uL - -#define NB_OF_ANALOG_BLOCKS 3u -#define SEE_RAM_WORD_SIZE 512 - -#define TS_ENABLE_MASK 0x01u -#define PPE_ENABLE_MASK 0x01u -#define ADC_RESET_MASK 0x10u -#define ADC_FIFO_CLR_MASK 0x04u -#define PDMA_DATAOUT_CLR_MASK 0x04u - - -/*-------------------------------------------------------------------------*//** - * - */ -extern ace_procedure_desc_t g_sse_sequences_desc_table[ACE_NB_OF_SSE_PROCEDURES]; - -/*-------------------------------------------------------------------------*//** - * - */ -sse_sequence_handle_t -ACE_get_sse_seq_handle -( - const uint8_t * p_sz_sequence_name -) -{ - uint16_t seq_idx; - sse_sequence_handle_t handle = INVALID_SSE_SEQ_HANDLE; - - for ( seq_idx = 0u; seq_idx < (uint32_t)ACE_NB_OF_SSE_PROCEDURES; ++seq_idx ) - { - if ( g_sse_sequences_desc_table[seq_idx].p_sz_proc_name != 0 ) - { - int32_t diff; - diff = strncmp( (const char *)p_sz_sequence_name, (const char *)g_sse_sequences_desc_table[seq_idx].p_sz_proc_name, MAX_PROCEDURE_NAME_LENGTH ); - if ( 0 == diff ) - { - /* channel name found. */ - handle = seq_idx; - break; - } - } - } - return handle; -} - -/*-------------------------------------------------------------------------*//** - * - */ -static uint32_t volatile * const sse_pc_ctrl_lut[NB_OF_ANALOG_BLOCKS] = -{ - &ACE->PC0_CTRL, - &ACE->PC1_CTRL, - &ACE->PC2_CTRL -}; - -static uint32_t volatile * const sse_pc_lo_lut[NB_OF_ANALOG_BLOCKS] = -{ - &ACE->PC0_LO, - &ACE->PC1_LO, - &ACE->PC2_LO -}; - -static uint32_t volatile * const sse_pc_hi_lut[NB_OF_ANALOG_BLOCKS] = -{ - &ACE->PC0_HI, - &ACE->PC1_HI, - &ACE->PC2_HI -}; - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_load_sse -( - sse_sequence_handle_t sequence -) -{ - ASSERT( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ); - - if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) - { - uint16_t i; - uint16_t offset; - const uint16_t * p_ucode; - - ASSERT( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS ); - - if ( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS ) - { - /* Stop relevant program counter. */ - *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_STOP; - - /* Load microcode into SEE RAM.*/ - p_ucode = g_sse_sequences_desc_table[sequence].sse_ucode; - offset = g_sse_sequences_desc_table[sequence].sse_load_offset; - - for ( i = 0u; i < g_sse_sequences_desc_table[sequence].sse_ucode_length; ++i ) - { - ACE->SSE_RAM_DATA[offset + i] = (uint32_t)*p_ucode; - ++p_ucode; - } - } - } -} - - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_start_sse -( - sse_sequence_handle_t sequence -) -{ - ASSERT( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ); - - if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) - { - uint16_t pc; - - ASSERT( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS ); - ASSERT( g_sse_sequences_desc_table[sequence].sse_load_offset < SEE_RAM_WORD_SIZE ); - - pc = g_sse_sequences_desc_table[sequence].sse_load_offset; - - if ( pc < 256u ) - { - *sse_pc_lo_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc; - } - else - { - *sse_pc_hi_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc - 256; - } - - *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_START; - - /* Enable Sample Sequencing Engine in case it was not done as part of - * system boot. */ - ACE->SSE_TS_CTRL |= TS_ENABLE_MASK; - } -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_restart_sse -( - sse_sequence_handle_t sequence -) -{ - ASSERT( sequence < ACE_NB_OF_SSE_PROCEDURES ); - ASSERT( g_sse_sequences_desc_table[sequence].sse_pc_id < NB_OF_ANALOG_BLOCKS ); - ASSERT( g_sse_sequences_desc_table[sequence].sse_load_offset < SEE_RAM_WORD_SIZE ); - - if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) - { - uint16_t pc; - - pc = g_sse_sequences_desc_table[sequence].sse_loop_pc; - - if ( pc < 256u ) - { - *sse_pc_lo_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc; - } - else - { - *sse_pc_hi_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = pc - 256; - } - - *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_START; - } -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_stop_sse -( - sse_sequence_handle_t sequence -) -{ - ASSERT( sequence < ACE_NB_OF_SSE_PROCEDURES ); - - if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) - { - /* Stop relevant program counter. */ - *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_STOP; - } -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_resume_sse -( - sse_sequence_handle_t sequence -) -{ - ASSERT( sequence < ACE_NB_OF_SSE_PROCEDURES ); - - if ( sequence < (sse_sequence_handle_t)ACE_NB_OF_SSE_PROCEDURES ) - { - *sse_pc_ctrl_lut[g_sse_sequences_desc_table[sequence].sse_pc_id] = SSE_START; - } -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_enable_sse_irq -( - sse_irq_id_t sse_irq_id -) -{ - ASSERT( sse_irq_id < NB_OF_SSE_FLAG_IRQS ); - - ACE->SSE_IRQ_EN |= 1uL << (uint32_t)sse_irq_id; -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_disable_sse_irq -( - sse_irq_id_t sse_irq_id -) -{ - ASSERT( sse_irq_id < NB_OF_SSE_FLAG_IRQS ); - - ACE->SSE_IRQ_EN &= (uint32_t)~(1uL << (uint32_t)sse_irq_id); -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_clear_sse_irq -( - sse_irq_id_t sse_irq_id -) -{ - ASSERT( sse_irq_id < NB_OF_SSE_FLAG_IRQS ); - - ACE->SSE_IRQ_CLR |= 1uL << (uint32_t)sse_irq_id; -} - -/*-------------------------------------------------------------------------*//** - * - */ -void ACE_clear_sample_pipeline(void) -{ - uint32_t saved_sse_ctrl; - uint32_t saved_ppe_ctrl; - - /* Pause the Sample Sequencing Engine. */ - saved_sse_ctrl = ACE->SSE_TS_CTRL; - ACE->SSE_TS_CTRL = ACE->SSE_TS_CTRL & ~((uint32_t)TS_ENABLE_MASK); - - /* Pause the Post Processing Engine. */ - saved_ppe_ctrl = ACE->PPE_CTRL; - ACE->PPE_CTRL = ACE->PPE_CTRL & ~((uint32_t)PPE_ENABLE_MASK); - - /* Reset the ADCs */ - ACE->ADC0_MISC_CTRL |= ADC_RESET_MASK; - ACE->ADC1_MISC_CTRL |= ADC_RESET_MASK; - ACE->ADC2_MISC_CTRL |= ADC_RESET_MASK; - - /* Clear ADC FIFOs */ - ACE->ADC0_FIFO_CTRL |= ADC_FIFO_CLR_MASK; - ACE->ADC1_FIFO_CTRL |= ADC_FIFO_CLR_MASK; - ACE->ADC2_FIFO_CTRL |= ADC_FIFO_CLR_MASK; - - /* clear DMA FIFOs */ - ACE->PPE_PDMA_CTRL |= PDMA_DATAOUT_CLR_MASK; - - /* Unpause the Post Processing Engine. */ - ACE->PPE_CTRL = saved_ppe_ctrl; - - /* Unpause the Sample Sequencing Engine. */ - ACE->SSE_TS_CTRL = saved_sse_ctrl; -} - -#ifdef __cplusplus -} -#endif - diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_transform.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_transform.c deleted file mode 100644 index 0a44a6aae..000000000 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/ace_transform.c +++ /dev/null @@ -1,467 +0,0 @@ -/******************************************************************************* - * (c) Copyright 2010 Actel Corporation. All rights reserved. - * - * This file contains the implementation of the functions used to dynamically - * control the linear transforms applied by the ACE post processing engine to - * the samples read from the SSE. - * - * SVN $Revision: 2908 $ - * SVN $Date: 2010-08-20 16:01:28 +0100 (Fri, 20 Aug 2010) $ - */ - -#include "mss_ace.h" -#include "mss_ace_configurator.h" -#include "mtd_data.h" -#include "envm_layout.h" -#include "../../CMSIS/a2fxxxm3.h" -#include "../../CMSIS/mss_assert.h" -#include "../../drivers_config/mss_ace/ace_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The ACE_set_linear_transform() is only available when using ACE configuration - * files generated by Libero 9.1 or later. - */ -#ifdef ACE_CFG_DATA_FORMAT_VERSION - -/*------------------------------------------------------------------------------ - * Masks ans shift values used to derive the ABPS ranges from the analog block - * configuration. - */ -#define ABPS1_CFG_BITS_MASK (uint32_t)0x06 -#define ABPS1_CFG_BITS_SHIFT (uint32_t)1 - -#define ABPS2_CFG_BITS_MASK (uint32_t)0x60 -#define ABPS2_CFG_BITS_SHIFT (uint32_t)5 - -/*------------------------------------------------------------------------------ - * One Bit DAC definitions. - */ -#define OBD_CURRENT (uint32_t)1 -#define OBD_VOLTAGE (uint32_t)0 - -#define OBD_MODE_MASK (uint32_t)0x01 -#define OBD_CHOPPING_MASK (uint32_t)0x02 - -/*-------------------------------------------------------------------------*//** - Neutral factor and offset for m*x + c trnasform. - */ -#define NEUTRAL_M_FACTOR 0x4000 -#define NEUTRAL_C_OFFSET 0x0000 - -/*-------------------------------------------------------------------------*//** - Enumearation of the various input channel types. This is used to differentiate - between channel types in order to extract the relevant factory calibration - data(m1 and c1). - */ -typedef enum channel_type -{ - ABPS1_CHAN = 0, - ABPS2_CHAN, - CMB_CHAN, - TMB_CHAN, - DIRECT_ADC_INPUT_CHAN, - OBDOUT_CHAN, - FLOATING_CHAN -} cal_channel_type_t; - -/*-------------------------------------------------------------------------*//** - This data structure is used to store factory calibration data for a specific - analog input. - */ -typedef struct __channel_calibration_t -{ - uint16_t mext; - uint16_t m1; - uint16_t c1; -} channel_calibration_t; - -/*-------------------------------------------------------------------------*//** - Local functions - */ -int32_t extend_sign -( - uint16_t x -); - -uint32_t adjust_to_24bit_ace_format -( - int64_t signed48 -); - -uint32_t adjust_to_16bit_ace_format -( - int64_t signed48 -); - -void get_calibration -( - adc_channel_id_t channel_id, - channel_calibration_t * p_calibration -); - -void write_transform_coefficients -( - ace_channel_handle_t channel_handle, - uint32_t m, - uint32_t c -); - -/*-------------------------------------------------------------------------*//** - - */ -extern const uint8_t g_ace_external_varef_used[ACE_NB_OF_ADC]; - -extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS]; - -extern const ppe_transforms_desc_t g_ace_ppe_transforms_desc_table[ACE_NB_OF_INPUT_CHANNELS]; - -/*------------------------------------------------------------------------------ - * Pointer to the manufacturing test data containing trimming information - * generated during manufacturing. - */ -static const mtd_data_t * const p_mtd_data = (mtd_data_t *)MTD_ADDRESS; - -/*-------------------------------------------------------------------------*//** - See "mss_ace.h" for details of how to use this function. - */ -int16_t ACE_get_default_m_factor -( - ace_channel_handle_t channel_handle -) -{ - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); - - return g_ace_ppe_transforms_desc_table[channel_handle].m_ppe_offset; -} - -/*-------------------------------------------------------------------------*//** - See "mss_ace.h" for details of how to use this function. - */ -int16_t ACE_get_default_c_offset -( - ace_channel_handle_t channel_handle -) -{ - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); - - return g_ace_ppe_transforms_desc_table[channel_handle].c_ppe_offset; -} - -/*-------------------------------------------------------------------------*//** - See "mss_ace.h" for details of how to use this function. - - m = m2 * m1 * mext - c = (m2 * c1 * mext) + (c2 * mext) - */ -void ACE_set_linear_transform -( - ace_channel_handle_t channel_handle, - int16_t m2, - int16_t c2 -) -{ - adc_channel_id_t channel_id; - uint32_t m; - uint32_t c; - int32_t m32; - int64_t m64; - int32_t c32; - int64_t c64_1; - int64_t c64_2; - uint16_t m1; - uint16_t c1; - uint16_t mext; - - channel_calibration_t calibration; - - ASSERT( channel_handle < NB_OF_ACE_CHANNEL_HANDLES ); - - if(channel_handle < NB_OF_ACE_CHANNEL_HANDLES) - { - channel_id = g_ace_channel_desc_table[channel_handle].signal_id; - - get_calibration(channel_id, &calibration); - - m1 = calibration.m1; - c1 = calibration.c1; - - mext = calibration.mext; - - /* - * m = m2 * m1 * mext - */ - m32 = extend_sign(m2) * extend_sign(m1); - m64 = (int64_t)m32 * extend_sign(mext); - - /* Convert 48-bit result to 32-bit ACE format result. */ - m = adjust_to_16bit_ace_format(m64); - - /* - * c = (m2 * c1 * mext) + (c2 * mext) - */ - c32 = extend_sign(m2) * extend_sign(c1); - c64_1 = (int64_t)c32 * extend_sign(mext); - - c64_2 = ((int64_t)(extend_sign(c2) * extend_sign(mext))) << 14; - - c = adjust_to_24bit_ace_format(c64_1 + c64_2); - - write_transform_coefficients(channel_handle, m, c); - } -} - -/*-------------------------------------------------------------------------*//** - Extend 16-bit signed number to 32-bit signed number. - */ -int32_t extend_sign -( - uint16_t x -) -{ - int32_t y; - const uint32_t sign_bit_mask = 0x00008000u; - - y = (x ^ sign_bit_mask) - sign_bit_mask; - - return y; -} - -/*-------------------------------------------------------------------------*//** - Take a 48-bit signed number, adjust it for saturation in the range -8 to - +7.999, translate into 24-bit ACE format. - */ -uint32_t adjust_to_24bit_ace_format -( - int64_t signed48 -) -{ - int32_t ace24_format; - const int64_t MAX_POSITIVE = 0x00001FFFFFFFFFFFuLL; /* +7.9999 */ - const int64_t MIN_NEGATIVE = 0xFFFF200000000000uLL; /* -8 */ - - /* Check saturation. */ - if(signed48 > MAX_POSITIVE) - { - signed48 = MAX_POSITIVE; - } - else if(signed48 < MIN_NEGATIVE) - { - signed48 = MIN_NEGATIVE; - } - - /* Adjust to 24-bit ACE format. */ - ace24_format = (uint32_t)(signed48 >> 14); - - return ace24_format; -} - -/*-------------------------------------------------------------------------*//** - Take a 48-bit signed number, adjust it for saturation in the range -8 to - +7.999, translate into 16-bit ACE format. - */ -uint32_t adjust_to_16bit_ace_format -( - int64_t signed48 -) -{ - int32_t ace24_format; - const int64_t MAX_POSITIVE = 0x00001FFFFFFFFFFFuLL; /* +7.9999 */ - const int64_t MIN_NEGATIVE = 0xFFFF200000000000uLL; /* -8 */ - - /* Check saturation. */ - if(signed48 > MAX_POSITIVE) - { - signed48 = MAX_POSITIVE; - } - else if(signed48 < MIN_NEGATIVE) - { - signed48 = MIN_NEGATIVE; - } - - /* Adjust to 24-bit ACE format. */ - ace24_format = (uint32_t)(signed48 >> 20); - - return ace24_format; -} - -/*-------------------------------------------------------------------------*//** - - */ -void get_calibration -( - adc_channel_id_t channel_id, - channel_calibration_t * p_calibration -) -{ - const uint32_t channel_mask = 0x0000000F; - const uint32_t CMB_MUX_SEL_MASK = 0x01; - const uint32_t TMB_MUX_SEL_MASK = 0x01; - - const cal_channel_type_t channel_type_lut[16] = - { - FLOATING_CHAN, - ABPS1_CHAN, - ABPS2_CHAN, - CMB_CHAN, - TMB_CHAN, - ABPS1_CHAN, - ABPS2_CHAN, - CMB_CHAN, - TMB_CHAN, - DIRECT_ADC_INPUT_CHAN, - DIRECT_ADC_INPUT_CHAN, - DIRECT_ADC_INPUT_CHAN, - DIRECT_ADC_INPUT_CHAN, - FLOATING_CHAN, - FLOATING_CHAN, - OBDOUT_CHAN - }; - - cal_channel_type_t channel_type; - uint32_t channel_nb; - uint32_t adc_nb; - uint32_t range; - uint32_t quad_id; - mtd_calibration_mc_t const * p_mc_coeff = 0; - - channel_nb = channel_id & channel_mask; - channel_type = channel_type_lut[channel_nb]; - adc_nb = ((uint32_t)channel_id & 0x30u) >> 4u; - - quad_id = adc_nb * 2; - - if ( (channel_nb > 4) && (channel_nb < 9) ) { ++quad_id; } - - switch ( channel_type ) - { - case ABPS1_CHAN: - range = (ACE->ACB_DATA[quad_id].b8 & ABPS1_CFG_BITS_MASK) >> ABPS1_CFG_BITS_SHIFT; - p_mc_coeff = &p_mtd_data->abps_calibration[quad_id][0][range]; - break; - - case ABPS2_CHAN: - range = (ACE->ACB_DATA[quad_id].b8 & ABPS2_CFG_BITS_MASK) >> ABPS2_CFG_BITS_SHIFT; - p_mc_coeff = &p_mtd_data->abps_calibration[quad_id][1][range]; - break; - - case CMB_CHAN: - { - uint32_t cmb_mux_sel = (uint32_t)ACE->ACB_DATA[quad_id].b9 & CMB_MUX_SEL_MASK; - if ( cmb_mux_sel == 0 ) - { /* current monitor */ - p_mc_coeff = &p_mtd_data->cm_calibration[quad_id]; - } - else - { /* direct input */ - p_mc_coeff = &p_mtd_data->quads_direct_input_cal[quad_id][0]; - } - } - break; - - case TMB_CHAN: - { - uint32_t tmb_mux_sel = (uint32_t)ACE->ACB_DATA[quad_id].b10 & TMB_MUX_SEL_MASK; - if ( tmb_mux_sel == 0 ) - { /* temperature monitor */ - p_mc_coeff = &p_mtd_data->tm_calibration[quad_id]; - } - else - { /* direct input */ - p_mc_coeff = &p_mtd_data->quads_direct_input_cal[quad_id][1]; - } - } - break; - - case DIRECT_ADC_INPUT_CHAN: - { - const uint32_t channel_to_direct_in_lut[16] - = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0}; - uint32_t direct_in_id; - - direct_in_id = channel_to_direct_in_lut[channel_id & channel_mask]; - p_mc_coeff = &p_mtd_data->adc_direct_input_cal[adc_nb][direct_in_id]; - } - break; - - case OBDOUT_CHAN: - { - uint32_t obd_mode = (uint32_t)ACE->ACB_DATA[quad_id].b6 & OBD_MODE_MASK; - uint32_t chopping_option = (uint32_t)ACE->ACB_DATA[quad_id].b6 & OBD_CHOPPING_MASK; - if (obd_mode > 0) - { - obd_mode = 1; - } - if (chopping_option > 0) - { - chopping_option = 1; - } - p_mc_coeff = &p_mtd_data->obd_calibration[adc_nb][obd_mode][chopping_option]; - } - break; - - case FLOATING_CHAN: - default: - /* Give neutral values is invalid channel. */ - p_calibration->m1 = NEUTRAL_M_FACTOR; - p_calibration->c1 = NEUTRAL_C_OFFSET; - break; - } - - if (p_mc_coeff != 0) - { - p_calibration->m1 = p_mc_coeff->m; - p_calibration->c1 = p_mc_coeff->c; - - } - - /*-------------------------------------------------------------------------- - Retrieve the value of the mext factor. This depends if external VAREF is - used by the ADC sampling the analog input channel. - */ - if (g_ace_external_varef_used[adc_nb]) - { - p_calibration->mext = p_mtd_data->global_settings.varef_m; - } - else - { - p_calibration->mext = NEUTRAL_M_FACTOR; - } -} - -/*-------------------------------------------------------------------------*//** - Write new m and c transform factors into the PPE RAM. The m and c factors - should be in 32-bit ACE number format. The factors will be merged with - relevant PE opcode into PPE RAM. The 32-bit factors are shifted right by one - byte giving a 24-bit ACE number which is then merged with an 8-bit PPE opcode - located in the most significant byte of the PPE RAM location. - */ -void write_transform_coefficients -( - ace_channel_handle_t channel_handle, - uint32_t m, - uint32_t c -) -{ - uint16_t m_ppe_offset; - uint16_t c_ppe_offset; - const uint32_t PPE_OPCODE_MASK = 0xFF000000u; - - m_ppe_offset = g_ace_ppe_transforms_desc_table[channel_handle].m_ppe_offset; - c_ppe_offset = g_ace_ppe_transforms_desc_table[channel_handle].c_ppe_offset; - - ACE->PPE_RAM_DATA[m_ppe_offset] - = (ACE->PPE_RAM_DATA[m_ppe_offset] & PPE_OPCODE_MASK) | (m >> 8u); - - ACE->PPE_RAM_DATA[c_ppe_offset] - = (ACE->PPE_RAM_DATA[c_ppe_offset] & PPE_OPCODE_MASK) | (c >> 8u); -} - -#endif /* ACE_CFG_DATA_FORMAT_VERSION */ - -#ifdef __cplusplus -} -#endif diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.c index cd717f036..ebd1e8dde 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.c +++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.c @@ -1,6 +1,6 @@ /******************************************************************************* * (c) Copyright 2009 Actel Corporation. All rights reserved. - * + * * SVN $Revision: 2905 $ * SVN $Date: 2010-08-20 14:03:28 +0100 (Fri, 20 Aug 2010) $ */ @@ -16,7 +16,7 @@ #ifdef __cplusplus extern "C" { -#endif +#endif #define START_ADC_CONVERSION 0x80uL @@ -31,8 +31,10 @@ void ace_init_convert(void); void ACE_init( void ) { /* Initialize driver's internal data. */ - ace_init_flags(); - + #if (ACE_NB_OF_PPE_FLAGS > 0) + ace_init_flags(); + #endif + /* Initialize the data structures used by conversion functions. */ ace_init_convert(); } @@ -70,13 +72,13 @@ uint16_t ACE_get_adc_result uint32_t data_valid; ASSERT( adc_id < NB_OF_ANALOG_MODULES ); - + if ( adc_id < (uint8_t)NB_OF_ANALOG_MODULES ) { do { data_valid = *adc_status_reg_lut[adc_id] & ADC_DATAVALID_MASK; } while ( !data_valid ); - + result = (uint16_t)(*adc_status_reg_lut[adc_id] & ADC_RESULT_MASK); } return result; @@ -88,7 +90,7 @@ uint16_t ACE_get_adc_result #define SDD_ENABLE_MASK 0x20uL #define SDD_REG_SEL_MASK 0x40uL - + #define DAC0_SYNC_EN_MASK 0x10uL #define DAC1_SYNC_EN_MASK 0x20uL #define DAC2_SYNC_EN_MASK 0x40uL @@ -149,7 +151,7 @@ void ACE_configure_sdd ) { ASSERT( sdd_id < NB_OF_SDD ); - + if ( sdd_id < NB_OF_SDD ) { const uint8_t sdd_2_quad_lut[NB_OF_SDD] = {0u, 2u, 4u}; @@ -157,16 +159,16 @@ void ACE_configure_sdd uint8_t obd_mode_idx = 1u; uint8_t chopping_mode_idx = 0u; uint32_t saved_pc2_ctrl; - + quad_id = sdd_2_quad_lut[sdd_id]; - + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ saved_pc2_ctrl = ACE->PC2_CTRL; ACE->PC2_CTRL = 0u; - + /* Select between voltage/current and RTZ modes.*/ ACE->ACB_DATA[quad_id].b6 = mode; - + /* Load manufacturing generated trim value. */ if ( (mode & OBD_MODE_MASK) > 0u ) { @@ -178,17 +180,17 @@ void ACE_configure_sdd } ACE->ACB_DATA[quad_id].b4 = p_mtd_data->odb_trimming[sdd_id][obd_mode_idx][chopping_mode_idx]; - + /* Restore SSE PC2 operations since no ACB accesses should take place * beyond this point. */ ACE->PC2_CTRL = saved_pc2_ctrl; - + /* Set SDD resolution. */ *dac_ctrl_reg_lut[sdd_id] = (uint32_t)resolution; - + /* Update SDD value through SSE_DACn_BYTES01. */ *dac_ctrl_reg_lut[sdd_id] |= SDD_REG_SEL_MASK; - + /* Synchronous or individual SDD update. */ if ( INDIVIDUAL_UPDATE == sync_update ) { @@ -210,7 +212,7 @@ void ACE_enable_sdd ) { ASSERT( sdd_id < NB_OF_SDD ); - + if ( sdd_id < NB_OF_SDD ) { *dac_ctrl_reg_lut[sdd_id] |= SDD_ENABLE_MASK; @@ -226,7 +228,7 @@ void ACE_disable_sdd ) { ASSERT( sdd_id < NB_OF_SDD ); - + if ( sdd_id < NB_OF_SDD ) { *dac_ctrl_reg_lut[sdd_id] &= ~SDD_ENABLE_MASK; @@ -243,7 +245,7 @@ void ACE_set_sdd_value ) { ASSERT( sdd_id < NB_OF_SDD ); - + if ( sdd_id < NB_OF_SDD ) { *dac_byte2_reg_lut[sdd_id] = sdd_value >> 16; @@ -262,9 +264,9 @@ void ACE_set_sdd_value_sync ) { uint32_t dac_sync_ctrl; - + dac_sync_ctrl = ACE->DAC_SYNC_CTRL; - + if ( SDD_NO_UPDATE != sdd0_value ) { ACE->DAC0_BYTE2 = sdd0_value >> 16; @@ -286,7 +288,7 @@ void ACE_set_sdd_value_sync ACE->SSE_DAC2_BYTES01 = sdd2_value; dac_sync_ctrl |= DAC2_SYNC_UPDATE; } - + ACE->DAC_SYNC_CTRL = dac_sync_ctrl; } @@ -357,23 +359,23 @@ void ACE_set_comp_reference { uint8_t scb_id; uint32_t odd; - + odd = (uint32_t)comp_id & 0x01uL; - + ASSERT( comp_id < NB_OF_COMPARATORS ); ASSERT( reference < NB_OF_COMP_REF ); ASSERT( odd ); /* Only Temperature block comparators have configurable reference input. */ - + if ( (comp_id < NB_OF_COMPARATORS) && (reference < NB_OF_COMP_REF) && (odd) ) { uint32_t saved_pc2_ctrl; - + scb_id = comp_id_2_scb_lut[comp_id]; - + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ saved_pc2_ctrl = ACE->PC2_CTRL; ACE->PC2_CTRL = 0u; - + if ( ADC_IN_COMP_REF == reference ) { ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK; @@ -384,7 +386,7 @@ void ACE_set_comp_reference ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK; ACE->ACB_DATA[scb_id].b11 = (ACE->ACB_DATA[scb_id].b11 & (uint8_t)~B11_DAC_MUXSEL_MASK) + (uint8_t)reference; } - + /* Restore SSE PC2 operations since no ACB accesses should take place * beyond this point. */ ACE->PC2_CTRL = saved_pc2_ctrl; @@ -401,22 +403,22 @@ void ACE_set_comp_hysteresis ) { uint8_t scb_id; - + ASSERT( comp_id < NB_OF_COMPARATORS ); ASSERT( hysteresis < NB_OF_HYSTERESIS ); - + if ( (comp_id < NB_OF_COMPARATORS) && (hysteresis < NB_OF_HYSTERESIS) ) { uint32_t odd; uint32_t saved_pc2_ctrl; - + scb_id = comp_id_2_scb_lut[comp_id]; odd = (uint32_t)comp_id & 0x01uL; - + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ saved_pc2_ctrl = ACE->PC2_CTRL; ACE->PC2_CTRL = 0u; - + if ( odd ) { /* Temperature monitor block comparator. */ @@ -427,7 +429,7 @@ void ACE_set_comp_hysteresis /* Current monitor block comparator. */ ACE->ACB_DATA[scb_id].b9 = (ACE->ACB_DATA[scb_id].b9 & HYSTERESIS_MASK) | (uint8_t)((uint8_t)hysteresis << HYSTERESIS_SHIFT); } - + /* Restore SSE PC2 operations since no ACB accesses should take place * beyond this point. */ ACE->PC2_CTRL = saved_pc2_ctrl; @@ -435,7 +437,7 @@ void ACE_set_comp_hysteresis } /*-------------------------------------------------------------------------*//** - + */ void ACE_enable_comp ( @@ -443,21 +445,21 @@ void ACE_enable_comp ) { uint8_t scb_id; - + ASSERT( comp_id < NB_OF_COMPARATORS ); - + if ( comp_id < NB_OF_COMPARATORS ) { uint32_t odd; uint32_t saved_pc2_ctrl; - + scb_id = comp_id_2_scb_lut[comp_id]; odd = (uint32_t)comp_id & 0x01uL; - + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ saved_pc2_ctrl = ACE->PC2_CTRL; ACE->PC2_CTRL = 0u; - + if ( odd ) { /* Temperature monitor block comparator. */ @@ -468,7 +470,7 @@ void ACE_enable_comp /* Current monitor block comparator. */ ACE->ACB_DATA[scb_id].b9 |= COMPARATOR_ENABLE_MASK; } - + /* Restore SSE PC2 operations since no ACB accesses should take place * beyond this point. */ ACE->PC2_CTRL = saved_pc2_ctrl; @@ -484,21 +486,21 @@ void ACE_disable_comp ) { uint8_t scb_id; - + ASSERT( comp_id < NB_OF_COMPARATORS ); - + if ( comp_id < NB_OF_COMPARATORS ) { uint32_t odd; uint32_t saved_pc2_ctrl; - + scb_id = comp_id_2_scb_lut[comp_id]; odd = (uint32_t)comp_id & 0x01uL; - + /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */ saved_pc2_ctrl = ACE->PC2_CTRL; ACE->PC2_CTRL = 0u; - + if ( odd ) { /* Temperature monitor block comparator. */ @@ -509,7 +511,7 @@ void ACE_disable_comp /* Current monitor block comparator. */ ACE->ACB_DATA[scb_id].b9 &= (uint8_t)~COMPARATOR_ENABLE_MASK; } - + /* Restore SSE PC2 operations since no ACB accesses should take place * beyond this point. */ ACE->PC2_CTRL = saved_pc2_ctrl; @@ -539,7 +541,7 @@ void ACE_enable_comp_rise_irq ) { ASSERT( comp_id < NB_OF_COMPARATORS ); - + ACE->COMP_IRQ_EN |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id); } @@ -552,7 +554,7 @@ void ACE_disable_comp_rise_irq ) { ASSERT( comp_id < NB_OF_COMPARATORS ); - + ACE->COMP_IRQ_EN &= ~(FIRST_RISE_IRQ_MASK << (uint32_t)comp_id); } @@ -565,7 +567,7 @@ void ACE_clear_comp_rise_irq ) { ASSERT( comp_id < NB_OF_COMPARATORS ); - + ACE->COMP_IRQ_CLR |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id); } @@ -578,7 +580,7 @@ void ACE_enable_comp_fall_irq ) { ASSERT( comp_id < NB_OF_COMPARATORS ); - + ACE->COMP_IRQ_EN |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id); } @@ -591,7 +593,7 @@ void ACE_disable_comp_fall_irq ) { ASSERT( comp_id < NB_OF_COMPARATORS ); - + ACE->COMP_IRQ_EN &= ~(FIRST_FALL_IRQ_MASK << (uint32_t)comp_id); } @@ -604,7 +606,7 @@ void ACE_clear_comp_fall_irq ) { ASSERT( comp_id < NB_OF_COMPARATORS ); - + ACE->COMP_IRQ_CLR |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id); } @@ -643,9 +645,9 @@ ACE_get_first_channel ) { ace_channel_handle_t channel_handle; - + channel_handle = (ace_channel_handle_t)0; - + return channel_handle; } @@ -659,12 +661,12 @@ ACE_get_next_channel ) { ++channel_handle; - + if ( channel_handle >= NB_OF_ACE_CHANNEL_HANDLES ) { channel_handle = (ace_channel_handle_t)0; } - + return channel_handle; } @@ -679,7 +681,7 @@ ACE_get_channel_handle { uint16_t channel_idx; ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE; - + for ( channel_idx = 0u; channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx ) { if ( g_ace_channel_desc_table[channel_idx].p_sz_channel_name != 0 ) @@ -708,7 +710,7 @@ ACE_get_input_channel_handle { uint16_t channel_idx; ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE; - + for ( channel_idx = 0u; channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx ) { if ( g_ace_channel_desc_table[channel_idx].signal_id == channel_id ) @@ -732,10 +734,10 @@ ACE_get_ppe_sample { uint16_t sample; uint16_t ppe_offset; - + ppe_offset = g_ace_channel_desc_table[channel_handle].signal_ppe_offset; sample = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset] >> 16u); - + return sample; } diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.h index ec4f00ed7..2acc01b1e 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.h +++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ace/mss_ace.h @@ -1,6 +1,6 @@ /******************************************************************************* * (c) Copyright 2009 Actel Corporation. All rights reserved. - * + * * SmartFusion ACE driver public API. * * SVN $Revision: 2884 $ @@ -101,13 +101,13 @@ • Sigma Delta Digital to Analog Converters (SDD) control • Direct analog block configuration and usage - + Initialization The ACE driver is initialized through a call to the ACE_init() function. The ACE_init() function must be called before any other ACE driver functions can be called. It initializes the ACE’s internal data. - + Reading analog input channels values and properties The ACE driver allows retrieving the most recent post processed sample value for each analog input. It also allows retrieving the name of the analog input @@ -129,7 +129,7 @@ • const uint8_t * ACE_get_channel_name( ace_channel_handle_t channel_handle ) • channel_type_t ACE_get_channel_type( ace_channel_handle_t channel_handle ) - + Post Processing Engine flags The SmartFusion ACE Post Processing Engine (PPE) provides the ability to monitor the state of analog input channels and detect when certain threshold values are @@ -162,7 +162,7 @@ • ace_flag_handle_t ACE_get_flag_handle (const uint8_t *p_sz_full_flag_name) • ace_flag_handle_t ACE_get_channel_first_flag (ace_channel_handle_t channel_handle, uint16_t *iterator) • ace_flag_handle_t ACE_get_channel_next_flag (ace_channel_handle_t channel_handle, uint16_t *iterator) - + The current status of a flag can be polled using the following function: • int32_t ACE_get_flag_status (ace_flag_handle_t flag_handle) @@ -203,7 +203,7 @@ • const uint8_t * ACE_get_flag_name (ace_flag_handle_t flag_handle) • ace_channel_handle_t ACE_get_flag_channel (ace_flag_handle_t flag_handle) - + Conversion to and from real world units The ACE driver provides a set of conversion functions to convert sample values read from the post processing engine into real world units: @@ -216,27 +216,27 @@ PPE sample values. These functions are typically used for dynamically adjusting flags threshold values. - + Sample Sequencing Engine control The ACE driver provides a set of functions for dynamically controlling the Sample Sequencing Engine. These functions are only required for managing multiple sampling sequences. The use of these functions is not required for most applications since the SSE is already configured and running by the time the application starts. - + Sample Sequencing Engine Interrupts Control The ACE driver provides a set of functions for managing interrupts generated by the Sample Sequencing Engine. These functions allow enabling, disabling and clearing interrupt defined as part of the sampling sequence. These functions also allow controlling interrupts generated by the ADCs. - + Comparators control The ACE driver provides a set of functions for managing interrupts generated based on the change of state of the high speed comparators. Functions are also provided to dynamically modify the comparators configuration. - + Sigma Delta Digital to Analog Converters (SDD) control The ACE driver provides functions for controlling the output value of the Sigma Delta DACs (SDD). Functions are also provided for dynamically adjusting the @@ -250,9 +250,9 @@ #ifdef __cplusplus extern "C" { -#endif +#endif -#include "../../drivers_config/mss_ace/ace_handles.h" +#include "ace_handles.h" /*-------------------------------------------------------------------------*//** Analog to Digital Converter channel IDs. @@ -325,7 +325,7 @@ void ACE_init( void ); /*============================================================================== ============== Direct Analog Block Configuration and Usage ==================== =============================================================================*/ - + /*=========================================================================*//** @defgroup group1 Direct Analog Block Configuration and Usage These functions are intended for using the SmartFusion analog block hardware @@ -338,10 +338,10 @@ void ACE_init( void ); channel identified by the channel_id parameter. This function is provided for test purposes. It must not be used while the Sample Sequencing Engine is running. - + @param channel_id The channel_id parameter identifies the analog input channel to sample. - + @return This function does not return a value. */ @@ -353,11 +353,11 @@ void ACE_start_adc /*-------------------------------------------------------------------------*//** The ACE_get_adc_result () function reads the result of the last input channel sampling performed by the ADC identified as parameter. - + @param adc_id The adc_id parameter identifies which of the possible three ADC to read the sample result from. - + @return The ACE_start_adc_sync() function returns the ADC result from the ADC specified as parameter. @@ -382,7 +382,7 @@ uint16_t ACE_get_adc_result /*-------------------------------------------------------------------------*//** The sdd_id_t enumeration is used to identify the Sigma Delta DACs to the SDD control functions, ACE_configure_sdd(), ACE_enable_sdd(), ACE_disable_sdd() - and ACE_set_sdd_value(). There is one SDD per analog module. + and ACE_set_sdd_value(). There is one SDD per analog module. */ typedef enum { @@ -394,7 +394,7 @@ typedef enum /*-------------------------------------------------------------------------*//** The sdd_resolution_t enumeration is used as a parameter to the - ACE_configure_sdd() function to specify DAC resolution of the Sigma Delta DAC. + ACE_configure_sdd() function to specify DAC resolution of the Sigma Delta DAC. */ typedef enum { @@ -435,21 +435,21 @@ typedef enum more important than accuracy. A call to this function is not required if relying on the configuration selected in the ACE configurator being loaded after reset by the system boot. - + @param sdd_id The sdd_id parameter specifies which Sigma Delta DAC is configured by this function. Allowed values are: - SDD0_OUT - SDD1_OUT - SDD2_OUT - + @param resolution The resolution parameter specifies the desired resolution of the Sigma Delta DAC. Allowed values are: - SDD_8_BITS - SDD_16_BITS - SDD_24_BITS - + @param mode The mode parameter specifies the operating mode of the Sigma Delta DAC. It specifies whether a current or voltage should be generated and whether @@ -459,7 +459,7 @@ typedef enum - SDD_VOLTAGE_MODE - SDD_RETURN_TO_ZERO - SDD_NON_RTZ - + @param sync_update The sync_update parameter specifies whether the SDD output will be updated individually though a call to ACE_set_sdd_value() or synchronously with one @@ -485,8 +485,8 @@ void ACE_configure_sdd ); /*-------------------------------------------------------------------------*//** - The ACE_enable_sdd() function is used to enable a Sigma Delta DAC. - + The ACE_enable_sdd() function is used to enable a Sigma Delta DAC. + @param sdd_id The sdd_id parameter specifies the Sigma Delta DAC to enable. */ @@ -497,7 +497,7 @@ void ACE_enable_sdd /*-------------------------------------------------------------------------*//** The ACE_disable_sdd() function is used to disable a Sigma Delta DAC. - + @param sdd_id The sdd_id parameter specifies the Sigma Delta DAC to disable. */ @@ -515,10 +515,10 @@ void ACE_disable_sdd the SDD resolution into account. A maximum voltage of 2.56V or a maximum current of 256uA will be generated when the sdd_value is set the maximum value allowed by the SDD resolution - + @param sdd_id The sdd_id parameter specifies which Sigma Delta DAC is being set. - + @param sdd_value The sdd_value parameter specifies the value of the Sigma Delta DAC output. It is a fraction of SDD resolution. The voltage/current value generated from @@ -605,17 +605,17 @@ void ACE_set_sdd_value_sync subsequently used as parameter to function ACE_get_ppe_sample() used to read the most recent post processed sample for the analog input identified through the channel/service name passed as argument to this function. - + @param p_sz_channel_name The p_sz_channel_name parameter is a zero-terminated string containing the name of the channel/service as entered in the ACE configurator. - + @return This function returns a channel handle. This channel handle is required as parameter to function ACE_get_ppe_sample(). It will return INVALID_CHANNEL_HANDLE if the channel/service name is not recognized. - + @code uint16_t adc_result; ace_channel_handle_t at0; @@ -632,10 +632,10 @@ ACE_get_channel_handle /*-------------------------------------------------------------------------*//** The ACE_get_input_channel_handle() function returns the channel handle for the hardware analog input channel specified as parameter. - + @param channel_id The channel_id parameter identifies a hardware analog input of the ACE. - + @return This function returns a channel handle. This channel handle is required as parameter to other ACE driver functions dealing with analog inputs. @@ -652,7 +652,7 @@ ACE_get_input_channel_handle The ACE_get_ppe_sample() function is used to read the most recent post processed sample for the analog input channel associated with the channel handle passed as parameter. - + @param channel_handle The channel_handle parameter identifies the analog input channel for which this function will return the most recent ADC conversion result adjusted for @@ -663,13 +663,13 @@ ACE_get_input_channel_handle ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @return This function returns a 16 bit value representing the adjusted value of the ADC conversion result for the analog input channel identified by the channel handle passed as parameter. The return value is actually a 12, 10 or 8 bits number depending on the configuration of the ADC. - + @code uint16_t adc_result; ace_channel_handle_t at0; @@ -688,7 +688,7 @@ ACE_get_ppe_sample associated with the channel handle passed as parameter. The channel name is the name used in the ACE configurator software tool when adding a service to the ACE. - + @param channel_handle The channel_handle parameter identifies the analog input channel for which we want to retrieve the channel name. The available channel handle values can @@ -697,7 +697,7 @@ ACE_get_ppe_sample to ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @return This function returns a pointer to a zero-terminated string containing the name of the channel. It returns 0 if the channel handle passed as parameter @@ -727,7 +727,7 @@ typedef enum analog input channel identified by the channel handle passed as parameter. This function allows determining whether the quantity measured through the ADC is a voltage, current or temperature. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -736,7 +736,7 @@ typedef enum ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @return This function returns one of the following values to report the type of quantity measure throught the channel: @@ -754,21 +754,21 @@ ACE_get_channel_type The ACE_get_channel_count() function returns the total number of configured analog input channels. It is the number of channels available for use as opposed to the theorical number of physical channels supported by the device. - + @return The ACE_get_channel_count() function returns the total number of input channels that were configured in the ACE configurator. The ACE_get_channel_count() function returns 0 if no input channels were configured. - + @code uint32_t inc; uint32_t nb_of_channels; ace_channel_handle_t current_channel; - + nb_of_channels = ACE_get_channel_count(); current_channel = ACE_get_first_channel(); - + for (inc = 0; inc < nb_of_channels; ++inc) { adc_result = ACE_get_ppe_sample( current_channel ); @@ -787,20 +787,20 @@ ACE_get_channel_count The ACE_get_first_channel() function returns the channel handle of one of the channel controlled by the ACE. This function is used to start iterating though the list of analog input channels handled by the ACE. - + @return The ACE_get_first_channel() function returns the first channel handle found in the ACE driver's internal channel handles list or INVALID_CHANNEL_HANDLE if there are no channels defined in the ACE configuration. - + @code uint32_t inc; uint32_t nb_of_channels; ace_channel_handle_t current_channel; - + nb_of_channels = ACE_get_channel_count(); current_channel = ACE_get_first_channel(); - + for (inc = 0; inc < nb_of_channels; ++inc) { adc_result = ACE_get_ppe_sample( current_channel ); @@ -819,7 +819,7 @@ ACE_get_first_channel The ACE_get_next_channel() returns the channel handle of the channel following the one passed as parameter. This function is used to iterate through the list of analog input channels handled by the ACE. - + @param channel_handle The channel_handle parameter identifies from which channel the driver should look in its channel handle list to return the next channel handle. The @@ -830,20 +830,20 @@ ACE_get_first_channel channel_handle returned by a previous call to ACE_get_first_channel(). The second and subsequent calls to ACE_get_next_channel() would typically use the channel_handle returned by a previous call to ACE_get_next_channel(). - + @return The ACE_get_next_channel() function returns the channel handle of the channel following the one passed as parameter or INVALID_CHANNEL_HANDLE if the end of the channels list has been reached. - + @code uint32_t inc; uint32_t nb_of_channels; ace_channel_handle_t current_channel; - + nb_of_channels = ACE_get_channel_count(); current_channel = ACE_get_first_channel(); - + for (inc = 0; inc < nb_of_channels; ++inc) { adc_result = ACE_get_ppe_sample( current_channel ); @@ -893,18 +893,18 @@ typedef uint16_t sse_sequence_handle_t; Sequencing Engine sequence identified by the sequence name passed as parameter. The sequence handler can then be used as parameter to other SSE sequence control functions to identify the sequence to control. - + @param p_sz_sequence_name The p_sz_sequence_name parameter is a pointer to a zero-terminated string containing the name of the sampling sequence for which we want to retrieve the handle. - + @return The ACE_get_sse_seq_handle() function returns the handle used to identify the sequence passed as parameter with other ACE driver sampling sequence control functions. It returns INVALID_SSE_SEQ_HANDLE if the sequence name passed as parameter is not recognized. - + @code sse_sequence_handle_t sse_seq_handle; sse_seq_handle = ACE_get_sse_seq_handle("ProcedureA"); @@ -925,7 +925,7 @@ ACE_get_sse_seq_handle The ACE_load_sse() function loads the ACE Sample Sequencing Engine (SSE) RAM with the microcode implementing the sampling sequence identified by the SSE sequence handler passed as parameter. - + @param sequence The sequence parameter is the SSE sequence handler identifying the sampling sequence to load into the ACE SSE. The value for this handler is retrieved @@ -943,7 +943,7 @@ void ACE_load_sse before the loop part of the sequence is started. You must ensure that the sampling sequence has been loaded into the ACE's SSE before calling this function. - + @param sequence The sequence parameter is the SSE sequence handler identifying the sampling sequence to load into the ACE SSE. The value for this handler is retrieved @@ -961,7 +961,7 @@ void ACE_start_sse intialization phase of the sequence. This function would typically be called after stopping the sampling sequence using the ACE_stop_see() function or with non-repeating sequences. - + @param sequence The sequence parameter is the SSE sequence handler identifying the sampling sequence to load into the ACE SSE. The value for this handler is retrieved @@ -975,7 +975,7 @@ void ACE_restart_sse /*-------------------------------------------------------------------------*//** The ACE_stop_sse() function stops execution of the Sample Sequencing Engine (SSE) sequence indentified by the sequence handle passed as parameter. - + @param sequence The sequence parameter is the SSE sequence handle identifying the sampling sequence to load into the ACE SSE. The value for this handler is retrieved @@ -991,7 +991,7 @@ void ACE_stop_sse sampling sequence identified by the sequence handle passed as parameter to resume execution. This function is typically used to restart execution of a sequence at the point where it was stopped through a call to ACE_stop_sse(). - + @param sequence The sequence parameter is the SSE sequence handler identifying the sampling sequence to load into the ACE SSE. The value for this handler is retrieved @@ -1008,7 +1008,7 @@ void ACE_resume_sse post processed samples within the ACE hardware. It is intended for use when switching between sampling sequences and using peripheral DMA. It avoids receiving stale samples generated as a result of a previous sampling sequence. - + The example below shows how this function can be used to ensure that no sample generated as a result of sampling sequence sequence_a will be generated once sampling sequence_b is started. Please note that it is important to stop the @@ -1019,7 +1019,7 @@ void ACE_resume_sse ACE_clear_sample_pipeline(); ACE_start_sse(sequence_b); @endcode - + The example below shows how to ensure that the first sample read through PDMA will be from the first channel in the sampling sequence. @code @@ -1028,9 +1028,9 @@ void ACE_resume_sse ACE_restart_sse(sequence_a); PDMA_start ( - PDMA_CHANNEL_0, - PDMA_ACE_PPE_DATAOUT, - (uint32_t)g_samples_buffer[g_pdma_buffer_idx], + PDMA_CHANNEL_0, + PDMA_ACE_PPE_DATAOUT, + (uint32_t)g_samples_buffer[g_pdma_buffer_idx], SAMPLES_BUFFER_SIZE ); @endcode @@ -1085,7 +1085,7 @@ typedef enum /*-------------------------------------------------------------------------*//** The ACE_enable_sse_irq() function enables the Sample Sequencing Engine (SSE) interrupt source specified as parameter to generate interrupts. - + @param sse_irq_id The sse_irq_id parameter identifies the SSE interrupt source controlled by this function. @@ -1098,7 +1098,7 @@ void ACE_enable_sse_irq /*-------------------------------------------------------------------------*//** The ACE_disable_sse_irq() function disables the Sample Sequencing Engine (SSE) interrupt source specified as parameter from generating interrupts. - + @param sse_irq_id The sse_irq_id parameter identifies the SSE interrupt source controlled by this function. @@ -1111,7 +1111,7 @@ void ACE_disable_sse_irq /*-------------------------------------------------------------------------*//** The ACE_clear_sse_irq() function clears the Sampling Sequencing Engine (SSE) interrupt specified as parameter. - + @param sse_irq_id The sse_irq_id parameter identifies the SSE interrupt source controlled by this function. @@ -1193,10 +1193,10 @@ typedef enum The ACE_set_comp_reference() function is used to select the reference input of a temperature monitor block comparator. The reference input of a temperature monitor can be an ADC direct input or one of the SDD's output. - + @param comp_id The comp_id parameter specifies the comparator for which to select the - reference input. Since only temperature monitor block comparators have a + reference input. Since only temperature monitor block comparators have a selectable reference input, allowed values are: - CMP1 - CMP3 @@ -1204,7 +1204,7 @@ typedef enum - CMP7 - CMP9 - CMP11 - + @param reference The reference parameter specify the signal that will be used as reference by the comparator. Allowed values are: @@ -1223,19 +1223,19 @@ void ACE_set_comp_reference The ACE_set_comp_hysteresis() function is used to set the hysteresis of a comparator. There are four possible hystereris settings: no hysteresis, +/-10mV, +/-30mV or +/-100mV. - + @param comp_id The comp_id parameter specifies the comparator for which this function will set the hyteresis. - + @param hysteresis - The hysteresis parameter specifies the hysteresis that will be applied to + The hysteresis parameter specifies the hysteresis that will be applied to the comparator's input. Allowed values are: - NO_HYSTERESIS - HYSTERESIS_10_MV - HYSTERESIS_30_MV - HYSTERESIS_100_MV - + */ void ACE_set_comp_hysteresis ( @@ -1246,7 +1246,7 @@ void ACE_set_comp_hysteresis /*-------------------------------------------------------------------------*//** The ACE_enable_comp() function is used to enable the comparator specified as parameter. - + @param comp_id The comp_id parameter specifies which comparator will be enabled by a call to this function. @@ -1259,7 +1259,7 @@ void ACE_enable_comp /*-------------------------------------------------------------------------*//** The ACE_disable_comp() function is used to disable the comparator specified as parameter. - + @param comp_id The comp_id parameter specifies which comparator will be disabled by a call to this function. @@ -1286,7 +1286,7 @@ void ACE_disable_comp - void ACE_Comp9_Rise_IRQHandler( void ); - void ACE_Comp10_Rise_IRQHandler( void ); - void ACE_Comp11_Rise_IRQHandler( void ); - + @param comp_id The comp_id parameter specifies which comparator will be enabled to generate rising interrupts. @@ -1300,7 +1300,7 @@ void ACE_enable_comp_rise_irq The ACE_disable_comp_rise_irq() function is used to disable interrupts from being generated when the positive input of the comparator specified as parameter rises above the negative input of the comparator. - + @param comp_id The comp_id parameter specifies which comparator will be disabled from generating rising interrupts. @@ -1313,11 +1313,11 @@ void ACE_disable_comp_rise_irq /*-------------------------------------------------------------------------*//** The ACE_clear_comp_rise_irq() function is used to clear rise interrupts. This function is typically called as part of the rise interrupt service routine. - + @param comp_id The comp_id parameter specifies the comparator for which to clear the rise interrupt. - + Example: @code void ACE_Comp1_Rise_IRQHandler( void ) @@ -1350,7 +1350,7 @@ void ACE_clear_comp_rise_irq - void ACE_Comp9_Fall_IRQHandler( void ); - void ACE_Comp10_Fall_IRQHandler( void ); - void ACE_Comp11_Fall_IRQHandler( void ); - + @param comp_id The comp_id parameter specifies which comparator will be enabled to generate fall interrupts. @@ -1364,7 +1364,7 @@ void ACE_enable_comp_fall_irq The ACE_disable_comp_fall_irq() function is used to disable interrupts from being generated when the positive input of the comparator specified as parameter falls below the negative input of the comparator. - + @param comp_id The comp_id parameter specifies which comparator will be disabled from generating fall interrupts. @@ -1377,11 +1377,11 @@ void ACE_disable_comp_fall_irq /*-------------------------------------------------------------------------*//** The ACE_clear_comp_fall_irq() function is used to clear fall interrupts. This function is typically called as part of the fall interrupt service routine. - + @param comp_id The comp_id parameter specifies the comparator for which to clear the fall interrupt. - + Example: @code void ACE_Comp1_Fall_IRQHandler( void ) @@ -1402,7 +1402,7 @@ void ACE_clear_comp_fall_irq status. It returns a 32 bit value indicating which comparators experienced a fall and/or rise event. These status bits can be cleared using the ACE_clear_comp_rise_irq() and ACE_clear_comp_fall_irq() functions. - + @return The return value is a 32 bit numnber where bits 0 to 11 indicate which comparator experienced a fall event and bits 21 to 23 indicate which @@ -1426,7 +1426,7 @@ uint32_t ACE_get_comp_status( void ); The ACE_is_hysteresis_flag() function indicates if an hysteresis is applied to the analog input sample value when determining the state of the flag identified as parameter. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1435,7 +1435,7 @@ uint32_t ACE_get_comp_status( void ); ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @return This function returns the value one if a hysteresis is applied to the channel sample values as part of determining the state of the flag identified as @@ -1450,7 +1450,7 @@ uint32_t ACE_is_hysteresis_flag The ACE_is_under_flag() function indicates whether a flag is triggered when the monitored analog input falls below the flag's threshold level or above the flag's threshold level. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1459,7 +1459,7 @@ uint32_t ACE_is_hysteresis_flag ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @return This function returns the value one if the flag identified as parameter triggers as a result of the monitored input falling below the flag's @@ -1482,7 +1482,7 @@ uint32_t ACE_is_under_flag over flag configured with a 100 millivolts hysteresis will result in the flag being asserted when the voltage reaches 1.1 volts and deasserted when the voltage falls below 0.9 volt. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1491,13 +1491,13 @@ uint32_t ACE_is_under_flag ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @param new_threshold The new_threshold parameter specifies the new threshold level that must be reached in order for the flag to be raised. The value of this parameter is the sample value resulting from a post processing engine conversion of the desired analog input threshold level. - + Example: The function below sets the threshold of the flag specified as parameter to 1 volt. @@ -1509,7 +1509,7 @@ uint32_t ACE_is_under_flag { uint16_t new_threshold; ace_channel_handle_t channel_handle; - + channel_handle = ACE_get_flag_channel(flag_handle); new_threshold = ACE_convert_from_mV(channel_handle, 1000); ACE_set_flag_threshold(flag_handle, new_threshold); @@ -1535,7 +1535,7 @@ void ACE_set_flag_threshold ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @param adc_hysteresis The adc_hysteresis parameter is the value to add and subtract to the threshold value to obtain the hysteresis high and low limits triggering flag @@ -1549,22 +1549,22 @@ void ACE_set_flag_threshold configurator for one of the analog inputs and one of the flags associated with that input. The method used to compute the adc_hysteresis value will work for all - input types including ABPS inputs where zero Volts is not equivalent to a + input types including ABPS inputs where zero Volts is not equivalent to a PPE sample value of zero. - + @code ace_channel_handle_t channel_handle; ace_flag_handle_t flag_handle; uint16_t adc_hysteresis; uint16_t upper_limit; uint16_t lower_limit; - + channel_handle = VoltageMonitor; flag_handle = VoltageMonitor_OVER_1V; - + upper_limit = ACE_convert_from_mV(channel_handle, 100); lower_limit = ACE_convert_from_mV(channel_handle, 0); - + if (upper_limit > lower_limit) { adc_hysteresis = upper_limit - lower_limit; @@ -1573,7 +1573,7 @@ void ACE_set_flag_threshold { adc_hysteresis = lower_limit - upper_limit; } - + ACE_set_flag_hysteresis(flag_handle, adc_hysteresis); @endcode */ @@ -1603,7 +1603,7 @@ ACE_set_flag_hysteresis ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @param assertion_value The assertion_value parameter is the Post Processing Engine sample value that must be reached for the flag, identified through the flag_handle parameter, @@ -1626,7 +1626,7 @@ void ACE_set_flag_assertion intended to be used where the threshold value is not centered within the hysteresis window. They allow specifying the actual threshold values at which the flag will be asserted and deasserted. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1635,7 +1635,7 @@ void ACE_set_flag_assertion ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @param assertion_value The assertion_value parameter is the Post Processing Engine sample value that must be reached for the flag, identified through the flag_handle @@ -1654,7 +1654,7 @@ void ACE_set_flag_deassertion analog input channel sample values when generating flags. It sets the hysteresis for all flags generated based on the value of the analog input channel identified by the channel handle passed as first parameter. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in @@ -1682,7 +1682,7 @@ ACE_set_channel_hysteresis /*-------------------------------------------------------------------------*//** * */ - + /*============================================================================== ================================== Flags ====================================== =============================================================================*/ @@ -1713,7 +1713,7 @@ ACE_set_channel_hysteresis by the flag name passed as parameter. The flag handle obtained through this function is then used as parameter to other flag control functions to identify which flag is to be controlled by the called function. - + @param p_sz_full_flag_name The p_sz_full_flag_name parameter is a pointer to a zero-terminated string holding the name of the flag as specified in the ACE configurator. The full @@ -1722,7 +1722,7 @@ ACE_set_channel_hysteresis For example, the full name for the flag called "CriticalOver" raised when the input channel called "MainSupply" reaches a critical level would be named "MainSupply:CriticalOver". - + @return The ACE_get_flag_handle() returns the flag handle associated with the flag name passed as parameter. It returns INVALID_FLAG_HANDLE when the flag name @@ -1738,7 +1738,7 @@ ACE_get_flag_handle The ACE_get_flag_status() function returns the current status of the flag specified as parameter. The flag is identified through the name specified in the ACE configurator when the flag was created. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1747,7 +1747,7 @@ ACE_get_flag_handle ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @return The ACE_get_flag_status() function returns one of the following values depending on the current status of the flag: @@ -1768,7 +1768,7 @@ ACE_get_flag_status sampled on the analog input channel identified as parameter are enabled to generate interrupts by this function. It enables flag interrupts both at the ACE PEE flag and Cortex-M3 interrupt controller levels. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -1791,7 +1791,7 @@ void ACE_enable_channel_flags_irq generating interrupts by this function. The interrupt is only disabled at the ACE PPE flag level in order to avoid disabling other cahnnel's flag interrupts which may happen to use the same ACE threshold interrupt line. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -1813,7 +1813,7 @@ void ACE_disable_channel_flags_irq sampled on the analog input channel identified as parameter are cleared by this function. This function would typically be used before enabling the flag interrupts in order to ignore past events. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -1833,7 +1833,7 @@ void ACE_clear_channel_flags_irq generated flags specified as parameter to interrupt the Cortex-M3 processor. It enables flag interrupts both at the ACE PPE flag and Cortex-M3 interrupt controller levels. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1853,7 +1853,7 @@ void ACE_enable_flag_irq generated flags from interrupting the Cortex-M3. The interrupt is only disabled at the ACE PPE flag level in order to avoid disabling other flags interrupts which may happen to use the same ACE threshold interrupt line. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1872,7 +1872,7 @@ void ACE_disable_flag_irq The ACE_clear_flag_irq() function clears the interrupt for the flag specified as parameter. This function would typically be used before enabling the flag interrupt in order to ignore past events. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1890,7 +1890,7 @@ void ACE_clear_flag_irq /*-------------------------------------------------------------------------*//** The ACE_get_flag_name() function returns the name of the flag identified by the flag handle passed as parameter. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1899,7 +1899,7 @@ void ACE_clear_flag_irq ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @return The ACE_get_flag_name() function returns a pointer to a zero-terminated string containing the name of the flag identified by the flag handle passed @@ -1915,7 +1915,7 @@ ACE_get_flag_name The ACE_get_flag_channel() function returns the handle of the channel monitored in order to generate the flag identified by the flag handle passed as parameter. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -1924,7 +1924,7 @@ ACE_get_flag_name ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @return The ACE_get_flag_channel() function returns a channel handle identifying the analog input channel monitored by the flag passed as parameter. @@ -1940,7 +1940,7 @@ ACE_get_flag_channel associated with the input channel specified by the channel_handle parameter. It indicates how many flags are generated based on the value of the specified analog input channel. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in @@ -1949,13 +1949,13 @@ ACE_get_flag_channel ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @return The ACE_get_channel_flag_count() function returns the total number of flags that are generated based on the value of the specified analog input channel. The ACE_get_channel_flag_count() function returns 0 if no input channels were configured. - + Example @code uint32_t inc; @@ -1963,10 +1963,10 @@ ACE_get_flag_channel uint16_t flag_iterator; ace_flag_handle_t current_flag; ace_channel_handle_t channel_handle; - + nb_of_flags = ACE_get_channel_flag_count(channel_handle); current_flag = ACE_get_channel_first_flag(channel_handle, &flag_iterator); - + for (inc = 0; inc < nb_of_flags; ++inc) { current_flag = ACE_get_channel_next_flag(channel_handle, &flag_iterator); @@ -1987,7 +1987,7 @@ ACE_get_channel_flag_count pointed to by the second function parameter. The iterator can be used subsequently as a parameter to the ACE_get_channel_next_flag() function to iterate through all flags associated with the analog input channel. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -1996,21 +1996,21 @@ ACE_get_channel_flag_count ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param iterator The iterator parameter is a pointer to a uint16_t iterator variable. The value of the iterator variable will be set by the ACE_get_channel_first_flag() functions so that it can be used in subsequent calls to ACE_get_channel_next_flag() to keep track of the current location in the list of flags associated with the analog input channel. - + @return The ACE_get_channel_first_flag() function returns a flag handle identifying one of the flags generated based on the value of the analog input channel identified by the channel_handle parameter. It returns INVALID_FLAG_HANDLE if no flags are generated based on the analog input channel input or if the channel handle is invalid. - + Example @code uint32_t inc; @@ -2018,10 +2018,10 @@ ACE_get_channel_flag_count uint16_t flag_iterator; ace_flag_handle_t current_flag; ace_channel_handle_t channel_handle; - + nb_of_flags = ACE_get_channel_flag_count(channel_handle); current_flag = ACE_get_channel_first_flag(channel_handle, &flag_iterator); - + for (inc = 0; inc < nb_of_flags; ++inc) { current_flag = ACE_get_channel_next_flag(channel_handle, &flag_iterator); @@ -2041,7 +2041,7 @@ ACE_get_channel_first_flag associated with the analog input channel identified by the channel handle passed as parameter. The retrieved flag handle is the next one in the driver's internal flag list based on the iterator parameter. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2050,14 +2050,14 @@ ACE_get_channel_first_flag ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param iterator The iterator parameter is a pointer to a uint16_t iterator variable. The value of the iterator variable will be set by the ACE_get_channel_first_flag() functions so that it can be used in subsequent calls to ACE_get_channel_next_flag() to keep track of the current location in the list of flags associated with the analog input channel. - + Example @code uint32_t inc; @@ -2065,10 +2065,10 @@ ACE_get_channel_first_flag uint16_t flag_iterator; ace_flag_handle_t current_flag; ace_channel_handle_t channel_handle; - + nb_of_flags = ACE_get_channel_flag_count(channel_handle); current_flag = ACE_get_channel_first_flag(channel_handle, &flag_iterator); - + for (inc = 0; inc < nb_of_flags; ++inc) { current_flag = ACE_get_channel_next_flag(channel_handle, &flag_iterator); @@ -2089,12 +2089,12 @@ ACE_get_channel_next_flag with the ACE driver and associated with a particular flag through the ACE_register_flag_isr() function. The ACE driver will call the flag handler function when the associated flag is raised. - + Declaring and Implementing PPE Flag Handler Functions PPE flag handler functions should follow the following prototype: void my_flag_handler ( ace_flag_handle_t flag_handle ); The actual name of the PPE flag handler is unimportant. You can use any name of - your choice for the PPE flag handler. + your choice for the PPE flag handler. The flag_handle parameter passes the handle of the raised flag to the flag handler function. */ @@ -2104,7 +2104,7 @@ typedef void (*flag_isr_t)( ace_flag_handle_t flag_handle ); The ACE_register_flag_isr() function is used to register a handler function with the ACE driver. The registered function will be called by the ACE driver when the associated flag is raised by the ACE post processing engine. - + @param flag_handle The flag_handle parameter identifies one of the flags generated based on the value of an analog input channel. The available flag handle values can be @@ -2113,33 +2113,33 @@ typedef void (*flag_isr_t)( ace_flag_handle_t flag_handle ); ACE_get_flag_handle() when the name of the flag is known, or by iterating though all flags associated with an analog input channel using the ACE_get_channel_first_flag() and ACE_get_channel_next_flag(). - + @param flag_isr The flag_isr parameter is a pointer to a flag handler function with the - following prototype: - void handler_function_name(ace_flag_handle_t flag_handle) + following prototype: + void handler_function_name(ace_flag_handle_t flag_handle) The flag handler function is called by the ACE driver as part of the relevant post processing engine flag interrupt service routine. It does not need to handle flag interrupt clearing as this is done by the ACE driver. - + @code void my_critical_handler( void ); - + void system_init( void ) { ace_flag_handle_t flag_handle; - + flag_handle = ACE_get_flag_handle( "MainSupply:CriticalLevel" ); ACE_register_flag_isr( flag_handle, my_critical_handler ); ACE_enable_flag_irq( flag_handle ); } - + void my_critical_handler( ace_flag_handle_t flag_handle ) { panic( flag_handle ); } - + @endcode */ void ACE_register_flag_isr @@ -2155,7 +2155,7 @@ void ACE_register_flag_isr channel through the ACE_register_channel_flags_isr() function. The ACE driver will call the channel flags handler function when one of the flags for the associated ADC input channel is raised. - + Declaring and Implementing PPE Channel Flag Handler Functions PPE channel flag handler functions should follow the following prototype: void my_channel_flag_handler ( ace_flag_handle_t flag_handle ); @@ -2172,7 +2172,7 @@ typedef void (*channel_flag_isr_t)( ace_flag_handle_t flag_handle ); handler will be called by the ACE driver when one of the flag generated based on the value of the analog input channel identified by the channel handle passed as parameter is asserted. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2181,30 +2181,30 @@ typedef void (*channel_flag_isr_t)( ace_flag_handle_t flag_handle ); ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param channel_flag_isr The channel_flag_isr parameter is pointer to a function taking a flag handle - as parameter. - void handler_function_name(ace_flag_handle_t flag_handle) + as parameter. + void handler_function_name(ace_flag_handle_t flag_handle) The flag handler function is called by the ACE driver as part of the relevant post processing engine flag interrupt service routine. It does not need to handle flag interrupt clearing as this is done by the ACE driver. - + Example The example below demonstrates the use of the ACE_register_channel_flags_isr() function in a system where the ACE is configured to have an analog input channels named "MainSupply" with one flag named "Critical" generated based on the value of "MainSupply" channel. The names "MainSupply" and "Critical" - were user selected in the ACE configurator. + were user selected in the ACE configurator. @code void main_supply_handler (ace_flag_handle_t flag_handle); - + void system_init(void) { ACE_register_channel_flag_isr(MainSupply, main_supply_handler); ACE_enable_channel_flags_irq(MainSupply); } - + void main_supply_handler (ace_flag_handle_t flag_handle) { if (MainSupply_Critical == flag_handle) @@ -2212,7 +2212,7 @@ typedef void (*channel_flag_isr_t)( ace_flag_handle_t flag_handle ); panic(flag_handle); } } - + @endcode */ void ACE_register_channel_flags_isr @@ -2227,12 +2227,12 @@ void ACE_register_channel_flags_isr registered with the ACE driver through the ACE_register_global_flags_isr() function. The ACE driver will call the global flags handler function when any flag for any ADC input channel is raised. - + Declaring and Implementing Global Flag Handler Functions PPE global flag handler functions should follow the following prototype: - void my_global_flag_handler( - ace_flag_handle_t flag_handle, - ace_channel_handle_t channel_handle + void my_global_flag_handler( + ace_flag_handle_t flag_handle, + ace_channel_handle_t channel_handle ); The actual name of the PPE global flag handler is unimportant. You can use any name of your choice for the PPE global flag handler. The flag_handle parameter @@ -2247,7 +2247,7 @@ typedef void (*global_flag_isr_t)( ace_flag_handle_t flag_handle, ace_channel_ha The ACE_register_global_flags_isr() function is used to register a global flag handler function with the ACE driver. The registered global handler will be called when any flag interrupt is generated. - + @param global_flag_isr The global_flag_isr parameter is a pointer to a function taking a flag handle and channel handle as parameter. @@ -2279,10 +2279,10 @@ void ACE_register_global_flags_isr ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param sample_value The sample_value parameter is the result of an analog to digital conversion. - + @return The ACE_convert_adc_input_to_mV() returns the number of millivolts derived from the ADC sample value passed as parameter. @@ -2296,7 +2296,7 @@ uint32_t ACE_convert_adc_input_to_mV /*-------------------------------------------------------------------------*//** The ACE_convert_to_mV() function converts a PPE sample value into milli-Volts. It handles prescaling adjusments based on ACE configuration for ABPS inputs. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2305,10 +2305,10 @@ uint32_t ACE_convert_adc_input_to_mV ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param sample_value The sample_value parameter is the result of an analog to digital conversion. - + @return The ACE_convert_to_mV() returns the number of millivolts derived from the PPE sample value passed as parameter. The returned value can be either @@ -2324,7 +2324,7 @@ int32_t ACE_convert_to_mV The ACE_convert_to_mA() function converts a PPE sample value into milli-Amps. The result of the conversion is only meaningful if the PPE sample value results from the conversion of a current monitor input. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2333,11 +2333,11 @@ int32_t ACE_convert_to_mV ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param sample_value The sample_value parameter is the result of an analog to digital conversion of the voltage generated by a current monitor analog block. - + @return The ACE_convert_to_mA() returns the number of milliamps derived from the PPE sample value passed as parameter. @@ -2352,7 +2352,7 @@ uint32_t ACE_convert_to_mA The ACE_convert_to_Kelvin() function converts a PPE sample value into degrees Kelvin. The result of the conversion is only meaningful if the PPE sample value results from the conversion of a temperature monitor input. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2361,11 +2361,11 @@ uint32_t ACE_convert_to_mA ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param sample_value The sample_value parameter is the result of an analog to digital conversion of the voltage generated by a temperature monitor analog block. - + @return The ACE_convert_to_Kelvin() returns the number of degrees Kelvin derived from the PPE sample value passed as parameter. @@ -2380,7 +2380,7 @@ uint32_t ACE_convert_to_Kelvin The ACE_convert_to_Celsius() function converts a PPE sample value into tenths of degrees Celsius. The result of the conversion is only meaningful if the PPE sample value results from the conversion of a temperature monitor input. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2389,11 +2389,11 @@ uint32_t ACE_convert_to_Kelvin ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param sample_value The sample_value parameter is the result of an analog to digital conversion of the voltage generated by a temperature monitor analog block. - + @return The ACE_convert_to_Celsius() returns the number of tenths of degrees Celsius derived from the PPE sample value passed as parameter. @@ -2408,7 +2408,7 @@ int32_t ACE_convert_to_Celsius The ACE_convert_to_Fahrenheit() function converts a PPE sample value into degrees Fahrenheit. The result of the conversion is only meaningful if the PPE sample value results from the conversion of a temperature monitor input. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2417,11 +2417,11 @@ int32_t ACE_convert_to_Celsius ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param sample_value The sample_value parameter is the result of an analog to digital conversion of the voltage generated by a temperature monitor analog block. - + @return The ACE_convert_to_Fahrenheit() returns the number of degrees Fahrenheit derived from the PPE sample value passed as parameter. @@ -2439,7 +2439,7 @@ int32_t ACE_convert_to_Fahrenheit This function is intended for use when directly controlling the ADC, not when using samples read from the PPE. It does not account for prescaling taking place before the ADC hardware input. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2448,11 +2448,11 @@ int32_t ACE_convert_to_Fahrenheit ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param voltage The voltage parameter is the milli-Volts voltage value for which we want this function to return the associated ADC sample result value. - + @return The ACE_convert_mV_to_adc_value() returns the ADC sample value that would be produced if the analog input channel identified by channel_handle was set to @@ -2470,7 +2470,7 @@ uint16_t ACE_convert_mV_to_adc_value voltage value on the analog input channel specified as parameter. This function handles prescaling adjusments based on ACE configuration for ABPS inputs. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2479,11 +2479,11 @@ uint16_t ACE_convert_mV_to_adc_value ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param voltage The voltage parameter is the milli-Volts voltage value for which we want this function to return the associated PPE sample result value. - + @return The ACE_convert_from_mV() returns the PPE sample value that would be produced if the analog input channel identified by channel_handle was set to the @@ -2501,7 +2501,7 @@ uint16_t ACE_convert_from_mV current value on the analog input channel specified as parameter. The result of the conversion is only meaningful if the analog input channel specified as parameter is configured as a current monitoring channel. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2510,11 +2510,11 @@ uint16_t ACE_convert_from_mV ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param current The current parameter is the milli-Amps current value for which we want this function to return the associated PPE sample result value. - + @return The ACE_convert_from_mA() returns the PPE sample value that would be produced if the analog input channel identified by channel_handle was set to the @@ -2532,7 +2532,7 @@ uint16_t ACE_convert_from_mA temperature value on the analog input channel specified as parameter. The result of the conversion is only meaningful if the analog input channel specified as parameter is configured as a temperature monitoring channel. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2541,11 +2541,11 @@ uint16_t ACE_convert_from_mA ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param temperature The temperature parameter is the degrees Kelvin temperature value for which we want this function to return the associated PPE sample result value. - + @return The ACE_convert_from_Kelvin() returns the PPE sample value that would be produced if the analog input channel identified by channel_handle was set to @@ -2563,7 +2563,7 @@ uint16_t ACE_convert_from_Kelvin temperature value on the analog input channel specified as parameter. The result of the conversion is only meaningful if the analog input channel specified as parameter is configured as a temperature monitoring channel. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2572,11 +2572,11 @@ uint16_t ACE_convert_from_Kelvin ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param temperature The temperature parameter is the degrees Celsius temperature value for which we want this function to return the associated PPE sample result value. - + @return The ACE_convert_from_Celsius() returns the PPE sample value that would be produced if the analog input channel identified by channel_handle was set to @@ -2594,7 +2594,7 @@ uint16_t ACE_convert_from_Celsius this temperature value on the analog input channel specified as parameter. The result of the conversion is only meaningful if the analog input channel specified as parameter is configured as a temperature monitoring channel. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in the @@ -2603,11 +2603,11 @@ uint16_t ACE_convert_from_Celsius ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param temperature The temperature parameter is the degrees Fahrenheit temperature value for which we want this function to return the associated PPE sample result value. - + @return The ACE_convert_from_Fahrenheit() returns the PPE sample value that would be produced if the analog input channel identified by channel_handle was set to @@ -2630,7 +2630,7 @@ uint16_t ACE_convert_from_Fahrenheit The PDMA sampling values are obtained by configuring the PDMA controller to transfer data from the ACE into a memory buffer. The ACE_translate_pdma_value() function is used to interpret the content of that memory buffer. - + Please note that the translation of PDMA data containing raw ADC values from ABPS inputs will result in sample values with an unexpected polarity. The returned sample value will have the opposite polarity to the actual analog @@ -2638,28 +2638,28 @@ uint16_t ACE_convert_from_Fahrenheit the analog front end that are normally hidden by the PPE processing of ADC raw samples. The translation of raw ADC values from analog inputs other than ABPS inputs will result in correct sample values. - + @param pdma_value The pdma_value parameter is a 32-bit value received from the ACE through a - peripheral DMA transfer. - + peripheral DMA transfer. + @param channel_id The channel_id parameter is a pointer to an ADC channel ID variable. It is used to return the ID of the ADC channel from which the PPE sample value was generated from. This parameter can be set to zero if retrieving the channel ID is not required. - + @return The ACE_translate_pdma_value() returns the PPE sample value extracted from the PDMA sampling value. - + Example: @code uint16_t ppe_value; uint16_t pdma_value; adc_channel_id_t channel_id; ace_channel_handle_t channel_handle; - + pdma_value = get_next_pdma_ace_sample(); ppe_value = ACE_translate_pdma_value(pdma_value, &channel_id); channel_handle = ACE_get_input_channel_handle(channel_id); @@ -2668,7 +2668,7 @@ uint16_t ACE_convert_from_Fahrenheit display_value(channel_handle, ppe_value); } @endcode - + */ uint16_t ACE_translate_pdma_value ( @@ -2686,7 +2686,7 @@ uint16_t ACE_translate_pdma_value - ACE_get_default_c_offset() - ACE_set_linear_transform() The post processing engine performs a linear transform on analog input samples - obtained from the sample sequencing engine. The main purpose of this linear + obtained from the sample sequencing engine. The main purpose of this linear transform is to apply part specific factory calibration to the analog samples in order to achieve high accuracy. A second user specified linear transform can also be optionally applied to the analog samples. This second linear @@ -2712,7 +2712,7 @@ uint16_t ACE_translate_pdma_value factor of the user defined linear transform applied by the post processing engine to analog samples. The user defined linear transform m factor default value is selected in the ACE configurator tool. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in @@ -2721,7 +2721,7 @@ uint16_t ACE_translate_pdma_value to ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @return The ACE_get_default_m_factor() function returns the user transform m factor default value. It is a signed 16-bit number representing a factor in the @@ -2738,7 +2738,7 @@ int16_t ACE_get_default_m_factor offset of the user defined linear transform applied by the post processing engine to analog samples. The user defined linear transform c offset default value is selected in the ACE configurator tool. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in @@ -2747,7 +2747,7 @@ int16_t ACE_get_default_m_factor to ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @return The ACE_get_default_c_offset() function returns the user linear transform’s c offset default value. It is a signed 16-bit number representing a factor @@ -2764,7 +2764,7 @@ int16_t ACE_get_default_c_offset linear transform applied to analog input samples by the post processing engine. The linear transform is of the form y = m.x + b where the m factor and c offset are in the range -2 to +1.99993896484375. - + @param channel_handle The channel_handle parameter identifies one of the analog input channels monitored by the ACE. The available channel handle values can be found in @@ -2773,27 +2773,27 @@ int16_t ACE_get_default_c_offset to ACE_get_channel_handle() when the name of the channel is known, or by iterating though all analog input channel using the ACE_get_first_channel() and ACE_get_next_channel(). - + @param m2 The m2 parameter specifies the user defined transform’s m factor. It is a signed 16-bit number representing a factor in the range -2 to +1.99993896484375. The value of the m2 factor is obtained by multiplying the parameter’s absolute value by 2^-14. For example, a value of 0x7000 represents a 1.75 factor and a value of 0xE000 represents a -0.5 factor. - + @param c2 The c2 parameter specifies the user defined transform’s c offset. It is a signed 16-bit number representing an offset in the range -2 to +1.99993896484375. The value of the c2 offset is obtained by multiplying the parameter’s absolute value by 2^-14. For example, a value of 0x1000 represents a 0.25 offset and a value of 0xB000 represents a -1.25 offset. - + @code void reset_to_default(ace_channel_handle_t channel_handle) { int16_t m; int16_t c; - + m = ACE_get_default_m_factor(channel_handle); c = ACE_get_default_c_offset(channel_handle); ACE_set_linear_transform(channel_handle, m, c); @@ -2808,7 +2808,7 @@ void ACE_set_linear_transform ); /** @} */ - + #ifdef __cplusplus } #endif diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c index 891cb888c..098e1d3b3 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c +++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c @@ -63,7 +63,7 @@ extern "C" { /* Allocating this many buffers will always ensure there is one free as, even though TX_RING_SIZE is set to two, the two Tx descriptors will only ever point to the same buffer. */ -#define macNUM_BUFFERS RX_RING_SIZE + TX_RING_SIZE + 1 +#define macNUM_BUFFERS RX_RING_SIZE + TX_RING_SIZE #define macBUFFER_SIZE 1488 /***************************************************************/ @@ -420,78 +420,94 @@ MSS_MAC_tx_packet configASSERT( usLength <= MSS_MAX_PACKET_SIZE ); } - /* Check if second descriptor is free, if it is then the first must - also be free. */ - if( ( ( (g_mss_mac.tx_descriptors[ 0 ].descriptor_0) & TDES0_OWN) == TDES0_OWN ) || ( ( (g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == TDES0_OWN ) ) + taskENTER_CRITICAL(); { - error = MAC_BUFFER_IS_FULL; + /* Check both Tx descriptors are free, meaning the double send has completed. */ + if( ( ( (g_mss_mac.tx_descriptors[ 0 ].descriptor_0) & TDES0_OWN) == TDES0_OWN ) || ( ( (g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == TDES0_OWN ) ) + { + error = MAC_BUFFER_IS_FULL; + } } + taskEXIT_CRITICAL(); + configASSERT( ( g_mss_mac.tx_desc_index == 0 ) ); if( error == MAC_OK ) { + /* Ensure nothing is going to get sent until both descriptors are ready. + This is done to prevent a Tx end occurring prior to the second descriptor + being ready. */ + MAC_BITBAND->CSR6_ST = 0u; + /* Assumed TX_RING_SIZE == 2. A #error directive checks this is the case. */ - for( ulDescriptor = 0; ulDescriptor < TX_RING_SIZE; ulDescriptor++ ) + taskENTER_CRITICAL(); { - g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 = 0u; - - if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) { - g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_AC; - } - - /* Every buffer can hold a full frame so they are always first and last - descriptor */ - g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_LS | TDES1_FS | TDES1_IC; - - /* set data size */ - g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= usLength; - - /* reset end of ring */ - g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER; - - if( usLength > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */ + for( ulDescriptor = 0; ulDescriptor < TX_RING_SIZE; ulDescriptor++ ) { - usLength = (uint16_t)MSS_TX_BUFF_SIZE; - } - - /* The data buffer is assigned to the Tx descriptor. */ - g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].buffer_1 = ( unsigned long ) uip_buf; - - /* update counters */ - desc = g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0; - if( (desc & TDES0_LO) != 0u ) { - g_mss_mac.statistics.tx_loss_of_carrier++; - } - if( (desc & TDES0_NC) != 0u ) { - g_mss_mac.statistics.tx_no_carrier++; - } - if( (desc & TDES0_LC) != 0u ) { - g_mss_mac.statistics.tx_late_collision++; - } - if( (desc & TDES0_EC) != 0u ) { - g_mss_mac.statistics.tx_excessive_collision++; - } - if( (desc & TDES0_UF) != 0u ) { - g_mss_mac.statistics.tx_underflow_error++; - } - g_mss_mac.statistics.tx_collision_count += - (desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK; - - /* Give ownership of descriptor to the MAC */ - g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0 = RDES0_OWN; - - g_mss_mac.tx_desc_index = (g_mss_mac.tx_desc_index + 1u) % (uint32_t)TX_RING_SIZE; - - MAC_start_transmission(); - MAC->CSR1 = 1u; - } + g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 = 0u; + + if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) { + g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_AC; + } + + /* Every buffer can hold a full frame so they are always first and last + descriptor */ + g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_LS | TDES1_FS; + + /* set data size */ + g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= usLength; + + /* reset end of ring */ + g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER; + + if( usLength > MSS_TX_BUFF_SIZE ) /* FLAG_EXCEED_LIMIT */ + { + usLength = (uint16_t)MSS_TX_BUFF_SIZE; + } + + /* The data buffer is assigned to the Tx descriptor. */ + g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].buffer_1 = ( unsigned long ) uip_buf; + + /* update counters */ + desc = g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0; + if( (desc & TDES0_LO) != 0u ) { + g_mss_mac.statistics.tx_loss_of_carrier++; + } + if( (desc & TDES0_NC) != 0u ) { + g_mss_mac.statistics.tx_no_carrier++; + } + if( (desc & TDES0_LC) != 0u ) { + g_mss_mac.statistics.tx_late_collision++; + } + if( (desc & TDES0_EC) != 0u ) { + g_mss_mac.statistics.tx_excessive_collision++; + } + if( (desc & TDES0_UF) != 0u ) { + g_mss_mac.statistics.tx_underflow_error++; + } + g_mss_mac.statistics.tx_collision_count += + (desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK; + + /* Give ownership of descriptor to the MAC */ + g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0 = TDES0_OWN; + + g_mss_mac.tx_desc_index = (g_mss_mac.tx_desc_index + 1u) % (uint32_t)TX_RING_SIZE; + } + } + taskEXIT_CRITICAL(); } if (error == MAC_OK) { error = (int32_t)usLength; + /* Start sending now both descriptors are set up. This is done to + prevent a Tx end occurring prior to the second descriptor being + ready. */ + MAC_BITBAND->CSR6_ST = 1u; + MAC->CSR1 = 1u; + /* The buffer pointed to by uip_buf is now assigned to a Tx descriptor. Find anothere free buffer for uip_buf. */ uip_buf = MAC_obtain_buffer(); @@ -594,8 +610,7 @@ MSS_MAC_rx_packet * will keep trying to read till time_out expires or data is read, if MSS_MAC_BLOCKING * value is given as time_out, function will wait for the reception to complete. * - * @param instance Pointer to a MAC_instance_t structure - * @param pacData The pointer to the packet data. + * @param pacData The pointer to the packet data. * @param time_out Time out value in milli seconds for receiving. * if value is #MSS_MAC_BLOCKING, there will be no time out. * if value is #MSS_MAC_NONBLOCKING, function will return immediately @@ -1057,8 +1072,7 @@ MSS_MAC_prepare_rx_descriptor (desc & (CSR8_MFO_MASK|CSR8_MFC_MASK)); /* Give ownership of descriptor to the MAC */ - g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 = - RDES0_OWN; + g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 = RDES0_OWN; g_mss_mac.rx_desc_index = (g_mss_mac.rx_desc_index + 1u) % RX_RING_SIZE; /* Start receive */ @@ -1431,10 +1445,19 @@ static void MAC_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n) */ void MSS_MAC_FreeTxBuffers( void ) { - if( ( ( (g_mss_mac.tx_descriptors[ 0 ].descriptor_0) & TDES0_OWN) == 0 ) && ( ( (g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == 0 ) ) + /* Check the buffers have not already been freed in the first of the + two Tx interrupts - which could potentially happen if the second Tx completed + during the interrupt for the first Tx. */ + if( g_mss_mac.tx_descriptors[ 0 ].buffer_1 != NULL ) { - MAC_release_buffer( ( unsigned char * ) g_mss_mac.tx_descriptors[ 0 ].buffer_1 ); - MAC_release_buffer( ( unsigned char * ) g_mss_mac.tx_descriptors[ 1 ].buffer_1 ); + if( ( ( (g_mss_mac.tx_descriptors[ 0 ].descriptor_0) & TDES0_OWN) == 0 ) && ( ( (g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == 0 ) ) + { + configASSERT( g_mss_mac.tx_descriptors[ 0 ].buffer_1 == g_mss_mac.tx_descriptors[ 1 ].buffer_1 ); + MAC_release_buffer( ( unsigned char * ) g_mss_mac.tx_descriptors[ 0 ].buffer_1 ); + + /* Just to mark the fact that the buffer has already been released. */ + g_mss_mac.tx_descriptors[ 0 ].buffer_1 == NULL; + } } } @@ -1447,19 +1470,72 @@ void MSS_MAC_FreeTxBuffers( void ) */ unsigned char *MAC_obtain_buffer( void ) { -long lIndex; +long lIndex, lAttempt = 0, lDescriptor, lBufferIsInUse; unsigned char *pcReturn = NULL; +unsigned char *pcBufferAddress; /* Find and return the address of a buffer that is not being used. Mark the buffer as now in use. */ - for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ ) + while( ( lAttempt <= 1 ) && ( pcReturn == NULL ) ) { - if( ucMACBufferInUse[ lIndex ] == pdFALSE ) + for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ ) { - pcReturn = &( xMACBuffers.ucBuffer[ lIndex ][ 0 ] ); - ucMACBufferInUse[ lIndex ] = pdTRUE; - break; + if( ucMACBufferInUse[ lIndex ] == pdFALSE ) + { + pcReturn = &( xMACBuffers.ucBuffer[ lIndex ][ 0 ] ); + ucMACBufferInUse[ lIndex ] = pdTRUE; + break; + } + } + + if( pcReturn == NULL ) + { + /* Did not find a buffer. That should not really happen, but could if + an interrupt was missed. See if any buffers are marked as in use, but + are not actually in use. */ + for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ ) + { + pcBufferAddress = &( xMACBuffers.ucBuffer[ lIndex ][ 0 ] ); + lBufferIsInUse = pdFALSE; + + /* Is the buffer used by an Rx descriptor? */ + for( lDescriptor = 0; lDescriptor < RX_RING_SIZE; lDescriptor++ ) + { + if( g_mss_mac.rx_descriptors[ lDescriptor ].buffer_1 == ( uint32_t ) pcBufferAddress ) + { + /* The buffer is in use by an Rx descriptor. */ + lBufferIsInUse = pdTRUE; + break; + } + } + + if( lBufferIsInUse != pdTRUE ) + { + /* Is the buffer used by an Tx descriptor? */ + for( lDescriptor = 0; lDescriptor < TX_RING_SIZE; lDescriptor++ ) + { + if( g_mss_mac.tx_descriptors[ lDescriptor ].buffer_1 == ( uint32_t ) pcBufferAddress ) + { + /* The buffer is in use by an Tx descriptor. */ + lBufferIsInUse = pdTRUE; + break; + } + } + } + + /* If the buffer was not found to be in use by either a Tx or an + Rx descriptor, but the buffer is marked as in use, then mark the + buffer to be in it's correct state of "not in use". */ + if( ( lBufferIsInUse == pdFALSE ) && ( ucMACBufferInUse[ lIndex ] == pdTRUE ) ) + { + ucMACBufferInUse[ lIndex ] = pdFALSE; + } + } } + + /* If any buffer states were changed it might be that a buffer can now + be obtained. Try again, but only one more time. */ + lAttempt++; } configASSERT( pcReturn ); diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h index 0578c4e0d..0a8578f97 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h +++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h @@ -31,12 +31,14 @@ typedef uint32_t addr_t; /***************************************************************************//** * Descriptor structure */ +#include "pack_struct_start.h" typedef struct { volatile uint32_t descriptor_0; volatile uint32_t descriptor_1; volatile uint32_t buffer_1; volatile uint32_t buffer_2; -} MAC_descriptor_t; +} MAC_descriptor_t +#include "pack_struct_end.h" /***************************************************************************//** @@ -74,6 +76,7 @@ typedef struct { uint8_t phy_address; /**< MII address of the connected PHY*/ + #include "pack_struct_start.h" struct { uint32_t rx_interrupts; /**< Number of receive interrupts occurred.*/ uint32_t rx_filtering_fail; /**< Number of received frames which did not pass @@ -111,7 +114,8 @@ typedef struct { uint32_t tx_collision_count; /**< Number of collisions occurred.*/ uint32_t tx_underflow_error; /**< Number of occurrences of; the FIFO was empty during the frame transmission.*/ - } statistics; + } statistics + #include "pack_struct_end.h" } MAC_instance_t #include "net/pack_struct_end.h" diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h index d4d2cc4df..8711243f4 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h +++ b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac_user_cfg.h @@ -1,6 +1,6 @@ /******************************************************************************* * (c) Copyright 2007 Actel Corporation. All rights reserved. - * + * * Actel:Firmware:MSS_Ethernet_MAC_Driver:2.0.103 configuration. * */ @@ -17,7 +17,7 @@ #define BUS_ARBITRATION_SCHEME 0 #define PROGRAMMABLE_BURST_LENGTH 0 -#define RX_RING_SIZE 4 +#define RX_RING_SIZE 5 #define SETUP_FRAME_TIME_OUT 10000 #define STATE_CHANGE_TIME_OUT 10000 #define TX_RING_SIZE 2 diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c deleted file mode 100644 index b49dca4ea..000000000 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.c +++ /dev/null @@ -1,413 +0,0 @@ -/******************************************************************************* - * (c) Copyright 2008 Actel Corporation. All rights reserved. - * - * SmartFusion microcontroller subsystem Peripheral DMA bare metal software - * driver implementation. - * - * SVN $Revision: 2110 $ - * SVN $Date: 2010-02-05 15:24:19 +0000 (Fri, 05 Feb 2010) $ - */ -#include "mss_pdma.h" -#include "../../CMSIS/mss_assert.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void DMA_IRQHandler( void ); -#else -void DMA_IRQHandler( void ); -#endif - -/***************************************************************************//** - Offset of the posted writes WRITE_ADJ bits in a PDMA channel's configuration - register. - */ -#define CHANNEL_N_POSTED_WRITE_ADJUST_SHIFT 14 - -/*-------------------------------------------------------------------------*//** - * Look-up table use to derice a channel's control register value from the - * requested source/destination. This table is incexed on the pdma_src_dest_t - * enumeration. - */ -#define CHANNEL_N_CTRL_PDMA_MASK (uint32_t)0x00000001 -#define CHANNEL_N_PERIPH_SELECT_SHIFT (uint32_t)23 -#define CHANNEL_N_DIRECTION_MASK (uint32_t)0x00000002 - -const uint32_t src_dest_to_ctrl_reg_lut[] = -{ - CHANNEL_N_CTRL_PDMA_MASK, /* PDMA_FROM_UART_0 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)1 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_UART_0 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)2 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_UART_1 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)3 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_UART_1 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)4 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_SPI_0 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)5 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_SPI_0 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)6 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_SPI_1 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)7 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_SPI_1 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)8 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_FPGA_1 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)8 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_FPGA_1 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)9 << CHANNEL_N_PERIPH_SELECT_SHIFT), /* PDMA_FROM_FPGA_0 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)9 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_FPGA_0 */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)10 << CHANNEL_N_PERIPH_SELECT_SHIFT) | CHANNEL_N_DIRECTION_MASK, /* PDMA_TO_ACE */ - CHANNEL_N_CTRL_PDMA_MASK | ( (uint32_t)11 << CHANNEL_N_PERIPH_SELECT_SHIFT) /* PDMA_FROM_ACE */ -}; - -/*-------------------------------------------------------------------------*//** - * - */ -#define PDMA_MASTER_ENABLE (uint32_t)0x04 -#define PDMA_SOFT_RESET (uint32_t)0x20 - -/*-------------------------------------------------------------------------*//** - * - */ -#define NB_OF_PDMA_CHANNELS 8 - -#define NEXT_CHANNEL_A 0U -#define NEXT_CHANNEL_B 1U - -#define CHANNEL_STOPPED 0U -#define CHANNEL_STARTED 1U - -static uint8_t g_pdma_next_channel[NB_OF_PDMA_CHANNELS]; -static uint8_t g_pdma_started_a[NB_OF_PDMA_CHANNELS]; -static uint8_t g_pdma_started_b[NB_OF_PDMA_CHANNELS]; -static pdma_channel_isr_t g_pdma_isr_table[NB_OF_PDMA_CHANNELS]; -static const uint16_t g_pdma_status_mask[NB_OF_PDMA_CHANNELS] = -{ - (uint16_t)0x0003, /* PDMA_CHANNEL_0 */ - (uint16_t)0x000C, /* PDMA_CHANNEL_1 */ - (uint16_t)0x0030, /* PDMA_CHANNEL_2 */ - (uint16_t)0x00C0, /* PDMA_CHANNEL_3 */ - (uint16_t)0x0300, /* PDMA_CHANNEL_4 */ - (uint16_t)0x0C00, /* PDMA_CHANNEL_5 */ - (uint16_t)0x3000, /* PDMA_CHANNEL_6 */ - (uint16_t)0xC000, /* PDMA_CHANNEL_7 */ -}; - - - -/***************************************************************************//** - * See mss_pdma.h for description of this function. - */ -void PDMA_init( void ) -{ - int32_t i; - - /* Enable PDMA master access to comms matrix. */ - SYSREG->AHB_MATRIX_CR |= PDMA_MASTER_ENABLE; - - /* Reset PDMA block. */ - SYSREG->SOFT_RST_CR |= PDMA_SOFT_RESET; - - /* Clear any previously pended MSS PDMA interrupt */ - NVIC_ClearPendingIRQ( DMA_IRQn ); - - /* Take PDMA controller out of reset*/ - SYSREG->SOFT_RST_CR &= ~PDMA_SOFT_RESET; - - /* Initialize channels state information. */ - for ( i = 0; i < NB_OF_PDMA_CHANNELS; ++i ) - { - g_pdma_next_channel[i] = NEXT_CHANNEL_A; - g_pdma_started_a[i] = CHANNEL_STOPPED; - g_pdma_started_b[i] = CHANNEL_STOPPED; - g_pdma_isr_table[i] = 0; - } -} - -/***************************************************************************//** - * See mss_pdma.h for description of this function. - */ -#define CHANNEL_RESET_MASK (uint32_t)0x00000020 - -void PDMA_configure -( - pdma_channel_id_t channel_id, - pdma_src_dest_t src_dest, - uint32_t channel_cfg, - uint8_t write_adjust -) -{ - /* Reset the channel. */ - PDMA->CHANNEL[channel_id].CRTL |= CHANNEL_RESET_MASK; - PDMA->CHANNEL[channel_id].CRTL &= ~CHANNEL_RESET_MASK; - - /* Configure PDMA channel's data source and destination. */ - if ( src_dest != PDMA_MEM_TO_MEM ) - { - PDMA->CHANNEL[channel_id].CRTL |= src_dest_to_ctrl_reg_lut[src_dest]; - } - - /* Configure PDMA channel trnasfer size, priority, source and destination address increment. */ - PDMA->CHANNEL[channel_id].CRTL |= channel_cfg; - - /* Posted write adjust. */ - PDMA->CHANNEL[channel_id].CRTL |= ((uint32_t)write_adjust << CHANNEL_N_POSTED_WRITE_ADJUST_SHIFT); -} - -/***************************************************************************//** - * See mss_pdma.h for description of this function. - */ -#define PAUSE_MASK (uint32_t)0x00000010 - -#define BUFFER_B_SELECT_MASK (uint32_t)0x00000004 - -#define CLEAR_PORT_A_DONE_MASK (uint32_t)0x00000080 -#define CLEAR_PORT_B_DONE_MASK (uint32_t)0x00000100 - -#define PORT_A_COMPLETE_MASK (uint32_t)0x00000001 -#define PORT_B_COMPLETE_MASK (uint32_t)0x00000002 - -void PDMA_start -( - pdma_channel_id_t channel_id, - uint32_t src_addr, - uint32_t dest_addr, - uint16_t transfer_count -) -{ - /* Pause transfer. */ - PDMA->CHANNEL[channel_id].CRTL |= PAUSE_MASK; - - /* Clear complete transfers. */ - if ( PDMA->CHANNEL[channel_id].STATUS & PORT_A_COMPLETE_MASK ) - { - PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_A_DONE_MASK; - g_pdma_started_a[channel_id] = CHANNEL_STOPPED; - } - if ( PDMA->CHANNEL[channel_id].STATUS & PORT_B_COMPLETE_MASK ) - { - PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_B_DONE_MASK; - g_pdma_started_b[channel_id] = CHANNEL_STOPPED; - } - - /* Load source, destination and transfer count. */ - if ( PDMA->CHANNEL[channel_id].STATUS & BUFFER_B_SELECT_MASK ) - { - g_pdma_next_channel[channel_id] = NEXT_CHANNEL_A; - g_pdma_started_b[channel_id] = CHANNEL_STARTED; - - PDMA->CHANNEL[channel_id].BUFFER_B_SRC_ADDR = src_addr; - PDMA->CHANNEL[channel_id].BUFFER_B_DEST_ADDR = dest_addr; - PDMA->CHANNEL[channel_id].BUFFER_B_TRANSFER_COUNT = transfer_count; - } - else - { - g_pdma_next_channel[channel_id] = NEXT_CHANNEL_B; - g_pdma_started_a[channel_id] = CHANNEL_STARTED; - - PDMA->CHANNEL[channel_id].BUFFER_A_SRC_ADDR = src_addr; - PDMA->CHANNEL[channel_id].BUFFER_A_DEST_ADDR = dest_addr; - PDMA->CHANNEL[channel_id].BUFFER_A_TRANSFER_COUNT = transfer_count; - } - - /* Start transfer */ - PDMA->CHANNEL[channel_id].CRTL &= ~PAUSE_MASK; -} - -/***************************************************************************//** - * See mss_pdma.h for description of this function. - */ -void PDMA_load_next_buffer -( - pdma_channel_id_t channel_id, - uint32_t src_addr, - uint32_t dest_addr, - uint16_t transfer_count -) -{ - if ( NEXT_CHANNEL_A == g_pdma_next_channel[channel_id] ) - { - /* Wait for channel A current transfer completion. */ - if ( CHANNEL_STARTED == g_pdma_started_a[channel_id] ) - { - uint32_t completed; - uint32_t channel_mask; - channel_mask = (uint32_t)1 << ((uint32_t)channel_id * 2U); - do { - completed = PDMA->BUFFER_STATUS & channel_mask; - } while( !completed ); - PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_A_DONE_MASK; - } - /* Load source, destination and transfer count. */ - PDMA->CHANNEL[channel_id].BUFFER_A_SRC_ADDR = src_addr; - PDMA->CHANNEL[channel_id].BUFFER_A_DEST_ADDR = dest_addr; - PDMA->CHANNEL[channel_id].BUFFER_A_TRANSFER_COUNT = transfer_count; - - /* Update channel state information. */ - g_pdma_next_channel[channel_id] = NEXT_CHANNEL_B; - g_pdma_started_a[channel_id] = CHANNEL_STARTED; - } - else - { - /* Wait for channel B current transfer completion. */ - if ( CHANNEL_STARTED == g_pdma_started_b[channel_id] ) - { - uint32_t completed; - uint32_t channel_mask; - channel_mask = (uint32_t)1 << (((uint32_t)channel_id * 2U) + 1U); - do { - completed = PDMA->BUFFER_STATUS & channel_mask; - } while( !completed ); - PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_B_DONE_MASK; - } - /* Load source, destination and transfer count. */ - PDMA->CHANNEL[channel_id].BUFFER_B_SRC_ADDR = src_addr; - PDMA->CHANNEL[channel_id].BUFFER_B_DEST_ADDR = dest_addr; - PDMA->CHANNEL[channel_id].BUFFER_B_TRANSFER_COUNT = transfer_count; - - /* Update channel state information. */ - g_pdma_next_channel[channel_id] = NEXT_CHANNEL_A; - g_pdma_started_b[channel_id] = CHANNEL_STARTED; - } -} - -/***************************************************************************//** - * See mss_pdma.h for description of this function. - */ -uint32_t PDMA_status -( - pdma_channel_id_t channel_id -) -{ - uint32_t status; - - status = PDMA->CHANNEL[channel_id].STATUS & (PORT_A_COMPLETE_MASK | PORT_B_COMPLETE_MASK); - - return status; -} - -/***************************************************************************//** - * - */ -#define CHANNEL_0_STATUS_BITS_MASK (uint16_t)0x0003 -#define CHANNEL_1_STATUS_BITS_MASK (uint16_t)0x000C -#define CHANNEL_2_STATUS_BITS_MASK (uint16_t)0x0030 -#define CHANNEL_3_STATUS_BITS_MASK (uint16_t)0x00C0 -#define CHANNEL_4_STATUS_BITS_MASK (uint16_t)0x0300 -#define CHANNEL_5_STATUS_BITS_MASK (uint16_t)0x0C00 -#define CHANNEL_6_STATUS_BITS_MASK (uint16_t)0x3000 -#define CHANNEL_7_STATUS_BITS_MASK (uint16_t)0xC000 - -static pdma_channel_id_t get_channel_id_from_status -( - uint16_t status -) -{ - pdma_channel_id_t channel_id = PDMA_CHANNEL_0; - - if ( status & CHANNEL_0_STATUS_BITS_MASK ) - { - channel_id = PDMA_CHANNEL_0; - } - else if ( status & CHANNEL_1_STATUS_BITS_MASK ) - { - channel_id = PDMA_CHANNEL_1; - } - else if ( status & CHANNEL_2_STATUS_BITS_MASK ) - { - channel_id = PDMA_CHANNEL_2; - } - else if ( status & CHANNEL_3_STATUS_BITS_MASK ) - { - channel_id = PDMA_CHANNEL_3; - } - else if ( status & CHANNEL_4_STATUS_BITS_MASK ) - { - channel_id = PDMA_CHANNEL_4; - } - else if ( status & CHANNEL_5_STATUS_BITS_MASK ) - { - channel_id = PDMA_CHANNEL_5; - } - else if ( status & CHANNEL_6_STATUS_BITS_MASK ) - { - channel_id = PDMA_CHANNEL_6; - } - else if ( status & CHANNEL_7_STATUS_BITS_MASK ) - { - channel_id = PDMA_CHANNEL_7; - } - else - { - ASSERT(0); - } - return channel_id; -} - -/***************************************************************************//** - * - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void DMA_IRQHandler( void ) -#else -void DMA_IRQHandler( void ) -#endif -{ - uint16_t status; - pdma_channel_id_t channel_id; - - status = (uint16_t)PDMA->BUFFER_STATUS; - - do { - channel_id = get_channel_id_from_status( status ); - status &= (uint16_t)~g_pdma_status_mask[channel_id]; - if ( 0 != g_pdma_isr_table[channel_id]) - { - g_pdma_isr_table[channel_id](); - } - } while ( 0U != status ); - - NVIC_ClearPendingIRQ( DMA_IRQn ); -} - -/***************************************************************************//** - * See mss_pdma.h for description of this function. - */ -void PDMA_set_irq_handler -( - pdma_channel_id_t channel_id, - pdma_channel_isr_t handler -) -{ - /* Save address of handler function in PDMA driver ISR lookup table. */ - g_pdma_isr_table[channel_id] = handler; - - /* Enable PDMA channel's interrupt. */ - PDMA->CHANNEL[channel_id].CRTL |= PDMA_IRQ_ENABLE_MASK; - - /* Enable PDMA interrupt in Cortex-M3 NVIC. */ - NVIC_EnableIRQ( DMA_IRQn ); -} - -/***************************************************************************//** - * See mss_pdma.h for description of this function. - */ -void PDMA_enable_irq( pdma_channel_id_t channel_id ) -{ - PDMA->CHANNEL[channel_id].CRTL |= PDMA_IRQ_ENABLE_MASK; - NVIC_EnableIRQ( DMA_IRQn ); -} - -/***************************************************************************//** - * See mss_pdma.h for description of this function. - */ -void PDMA_clear_irq -( - pdma_channel_id_t channel_id -) -{ - /* Clear interrupt in PDMA controller. */ - PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_A_DONE_MASK; - PDMA->CHANNEL[channel_id].CRTL |= CLEAR_PORT_B_DONE_MASK; - - /* Clear interrupt in Cortex-M3 NVIC. */ - NVIC_ClearPendingIRQ( DMA_IRQn ); -} - -#ifdef __cplusplus -} -#endif - diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h deleted file mode 100644 index 6f79226c3..000000000 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_pdma/mss_pdma.h +++ /dev/null @@ -1,703 +0,0 @@ -/******************************************************************************* - * (c) Copyright 2008 Actel Corporation. All rights reserved. - * - * SmartFusion microcontroller subsystem Peripheral DMA bare metal software - * driver public API. - * - * SVN $Revision: 2110 $ - * SVN $Date: 2010-02-05 15:24:19 +0000 (Fri, 05 Feb 2010) $ - */ -/*=========================================================================*//** - @mainpage SmartFusion MSS GPIO Bare Metal Driver. - - @section intro_sec Introduction - The SmartFusion Microcontroller Subsystem (MSS) includes an 8 channel - Peripheral DMA (PDMA) controller. - This software driver provides a set of functions for controlling the MSS PDMA - controller as part of a bare metal system where no operating system is available. - This driver can be adapted for use as part of an operating system but the - implementation of the adaptation layer between this driver and the operating - system's driver model is outside the scope of this driver. - - @section theory_op Theory of Operation - The MSS PDMA driver uses the SmartFusion "Cortex Microcontroler Software - Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access MSS hardware - registers. You must ensure that the SmartFusion CMSIS-PAL is either included - in the software toolchain used to build your project or is included in your - project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using - the Actel Firmware Catalog. - - The MSS PDMA driver functions are grouped into the following categories: - - Initialization - - Configuration - - DMA transfer control - - Interrupt control - - The MSS PDMA driver is initialized through a call to the PDMA_init() function. - The PDMA_init() function must be called before any other PDMA driver functions - can be called. - - Each PDMA channel is individually configured through a call to the PDMA_configure() - function. Configuration includes: - - channel priority - - transfer size - - source and/or destination address increment - - source or destination of the DMA transfer - PDMA channels can be divided into high and low priority channels. High priority - channels are given more opportunities to perform transfers than low priority - channels when there are continuous high priority channels requests. The ratio - of high priority to low priority PDMA transfers is configurable through the - PDMA_set_priority() function. - PDMA channels can be configured to perform byte (8 bits), half-word (16 bits) - or word (32 bits) transfers. - The source and destination address of a PDMA channel’s transfers can be - independently configured to increment by 0, 1, 2 or 4 bytes. For example, the - content of a byte buffer located in RAM can be transferred into a peripheral’s - transmit register by configuring the source address increment to one byte and - no increment of the destination address. - The source or destination of a PDMA channel’s transfers can be configured to - be one of the MSS peripherals. This allows the PDMA controller to use some - hardware flow control signaling with the peripheral to avoid overrunning the - peripheral’s data buffer when the peripheral is the destination of the DMA - transfer, or attempting to read data from the peripheral while it is not ready - when the peripheral is the source of the transfer. - A PDMA channel can also be configured to transfer data between two memory - mapped locations (memory to memory). No hardware flow control is used by the - PDMA controller for data transfer in this configuration. - - A DMA transfer can be initiated by a call to the PDMA_start() function after a - PDMA channel has been configured. Once started, further data can be pushed - through the PDMA channel by calling the PDMA_load_next_buffer() function. The - PDMA_load_next_buffer() function can be called every time a call to the - PDMA_status() function indicates that the PDMA channel used for the transfer - has a free buffer or it can be called as a result of a PDMA interrupt. - - A DMA transfer can be paused and resumed through calls to functions PDMA_pause() - and PDMA_resume(). - - Your application can manage DMA transfers using interrupts through the use of - the following functions: - - PDMA_set_irq_handler() - - PDMA_enable_irq() - - PDMA_clear_irq() - - PDMA_disable_irq() - The PDMA_set_irq_handler() function is used to register PDMA channel interrupt - handler functions with the driver. You must create and register an interrupt - handler function for each interrupt driven PDMA channel used by the application. - Use the PDMA_enable_irq() function to enable interrupts for the PDMA channels. - Every time a PDMA channel completes the transfer of a buffer it causes a PDMA - interrupt to occur and the PDMA driver will call the interrupt handler - registered by the application for that PDMA channel. - - *//*=========================================================================*/ -#ifndef __MSS_PERIPHERAL_DMA_H_ -#define __MSS_PERIPHERAL_DMA_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "../../CMSIS/a2fxxxm3.h" - -/***************************************************************************//** - The pdma_channel_id_t enumeration is used to identify peripheral DMA channels. - It is used as function parameter to specify the PDMA channel used. - */ -typedef enum __pdma_channel_id -{ - PDMA_CHANNEL_0 = 0, - PDMA_CHANNEL_1, - PDMA_CHANNEL_2, - PDMA_CHANNEL_3, - PDMA_CHANNEL_4, - PDMA_CHANNEL_5, - PDMA_CHANNEL_6, - PDMA_CHANNEL_7 -} pdma_channel_id_t; - -/***************************************************************************//** - The pdma_src_dest_t enumeration is used to specify the source or destination - of transfers on a PDMA channel. It specifies which hardware peripheral will be - the source or destination of DMA transfers. This allows the PDMA controller - to use hardware flow control signals to avoid overrunning a - destination peripheral with data it is not ready to receive, or attempting to - transfer data from a peripheral while it has no data ready to transfer. - The pdma_src_dest_t enumeration can also be used to specify that a PDMA channel - is configured to transfer data between two memory mapped locations - (memory to memory). No hardware data flow control is used by the PDMA - controller in this configuration. - This enumeration is used as parameter to function PDMA_configure(). - */ -typedef enum __pdma_src_dest -{ - PDMA_FROM_UART_0 = 0, - PDMA_TO_UART_0, - PDMA_FROM_UART_1, - PDMA_TO_UART_1, - PDMA_FROM_SPI_0, - PDMA_TO_SPI_0, - PDMA_FROM_SPI_1, - PDMA_TO_SPI_1, - PDMA_FROM_FPGA_1, - PDMA_TO_FPGA_1, - PDMA_FROM_FPGA_0, - PDMA_TO_FPGA_0, - PDMA_TO_ACE, - PDMA_FROM_ACE, - PDMA_MEM_TO_MEM -} pdma_src_dest_t; - -/***************************************************************************//** - The pdma_priority_ratio_t enumeration is used to configure the ratio of high - priority to low priority PDMA channels. This ratio specifies how many DMA - transfer opportunities will be given to high priority channels before a DMA - transfer opportunity is given to a low priority channel when there are - continuous requests from high priority channels. This enumeration is used as - parameter to function PDMA_set_priority_ratio(). - */ -typedef enum __pdma_priority_ratio_t -{ - PDMA_ROUND_ROBIN = 0, - PDMA_RATIO_HIGH_LOW_1_TO_1 = 1, - PDMA_RATIO_HIGH_LOW_3_TO_1 = 3, - PDMA_RATIO_HIGH_LOW_7_TO_1 = 7, - PDMA_RATIO_HIGH_LOW_15_TO_1 = 15, - PDMA_RATIO_HIGH_LOW_31_TO_1 = 31, - PDMA_RATIO_HIGH_LOW_63_TO_1 = 63, - PDMA_RATIO_HIGH_LOW_127_TO_1 = 127, - PDMA_RATIO_HIGH_LOW_255_TO_1 = 255 -} pdma_priority_ratio_t; - - -/***************************************************************************//** - The pdma_channel_isr_t type is a pointer to a PDMA channel interrupt handler - function. It specifies the function prototype of functions that can be - registered as PDMA channel interrupt handlers. It is used as parameter to - function PDMA_set_irq_handler(). - */ -typedef void (*pdma_channel_isr_t)( void ); -/***************************************************************************//** - These constants are used to build the channel_cfg parameter of the - PDMA_configure() function. They specify whether a channel is a high or low - priority channel. - */ -#define PDMA_LOW_PRIORITY 0x0000 -#define PDMA_HIGH_PRIORITY 0x0200 - -/***************************************************************************//** - These constants are used to build the channel_cfg parameter of the - PDMA_configure() function. They specify the data width of the transfers - performed by a PDMA channel. - */ -#define PDMA_BYTE_TRANSFER 0x0000 /* Byte transfers (8 bits) */ -#define PDMA_HALFWORD_TRANSFER 0x0004 /* Half-word transfers (16 bits) */ -#define PDMA_WORD_TRANSFER 0x0008 /* Word transfers (32 bits) */ - -/***************************************************************************//** - These constants are used to build the channel_cfg parameter of the - PDMA_configure() function. They specify the PDMA channel’s source and - destination address increment. - */ -#define PDMA_NO_INC 0 -#define PDMA_INC_SRC_ONE_BYTE 0x0400 -#define PDMA_INC_SRC_TWO_BYTES 0x0800 -#define PDMA_INC_SRC_FOUR_BYTES 0x0C00 -#define PDMA_INC_DEST_ONE_BYTE 0x1000 -#define PDMA_INC_DEST_TWO_BYTES 0x2000 -#define PDMA_INC_DEST_FOUR_BYTES 0x3000 - -/***************************************************************************//** - * Mask for various control register bits. - */ -#define PDMA_IRQ_ENABLE_MASK (uint32_t)0x00000040 -#define PDMA_PAUSE_MASK (uint32_t)0x00000010 - -/***************************************************************************//** - These constants are used to specify the src_addr parameter to the PDMA_start() - and PDMA_load_next_buffer() functions. They specify the receive register - address of peripherals that can be the source of a DMA transfer. - When a PDMA channel is configured for DMA transfers from a peripheral to memory, - the constant specifying that peripheral’s receive register address must be used - as the src_addr parameter. - */ -#define PDMA_SPI0_RX_REGISTER 0x40001010uL -#define PDMA_SPI1_RX_REGISTER 0x40011010uL -#define PDMA_UART0_RX_REGISTER 0x40000000uL -#define PDMA_UART1_RX_REGISTER 0x40010000uL -#define PDMA_ACE_PPE_DATAOUT 0x40021308uL - -/***************************************************************************//** - These constants are used to specify the dest_addr parameter to the PDMA_start() - and PDMA_load_next_buffer() functions. They specify the transmit register - address of peripherals that can be the destination of a DMA transfer. - When a PDMA channel is configured for DMA transfers from memory to a peripheral, - the constant specifying that peripheral’s transmit register address must be used - as the dest_addr parameter. - */ -#define PDMA_SPI0_TX_REGISTER 0x40001014uL -#define PDMA_SPI1_TX_REGISTER 0x40011014uL -#define PDMA_UART0_TX_REGISTER 0x40000000uL -#define PDMA_UART1_TX_REGISTER 0x40010000uL -#define PDMA_ACE_SSE_DATAIN 0x40020700uL - -/***************************************************************************//** - The PDMA_DEFAULT_WRITE_ADJ constant provides a suitable default value for the - PDMA_configure() function write_adjust parameter. - */ -#define PDMA_DEFAULT_WRITE_ADJ 10u - -/***************************************************************************//** - The PDMA_init() function initializes the peripheral DMA hardware and driver - internal data. It resets the PDMA and it also clears any pending PDMA - interrupts in the Cortex-M3 interrupt controller. When the function exits, it - takes the PDMA block out of reset. - */ -void PDMA_init( void ); - -/***************************************************************************//** - The PDMA_configure() function configures a PDMA channel. - It specifies: - - The peripheral which will be the source or destination of the DMA transfer. - - Whether the DMA channel will be a high or low priority channel - - The source and destination address increment that will take place after - each transfer. - - @param channel_id - The channel_id parameter identifies the PDMA channel used by the function. - - @param src_dest - The src_dest parameter specifies the source or destination of the DMA - transfers that will be performed. It can be one of the following: - - PDMA_FROM_UART_0 - - PDMA_TO_UART_0 - - PDMA_FROM_UART_1 - - PDMA_TO_UART_1 - - PDMA_FROM_SPI_0 - - PDMA_TO_SPI_0 - - PDMA_FROM_SPI_1 - - PDMA_TO_SPI_1 - - PDMA_FROM_FPGA_1 - - PDMA_TO_FPGA_1 - - PDMA_FROM_FPGA_0 - - PDMA_TO_FPGA_0 - - PDMA_TO_ACE - - PDMA_FROM_ACE - - PDMA_MEM_TO_MEM - - @param channel_cfg - The channel_cfg parameter specifies the configuration of the PDMA channel. - The configuration includes: - - channel priority - - transfer size - - source and/or destination address increment - The channel_cfg parameter value is a logical OR of: - One of the following to specify the channel priority: - - PDMA_LOW_PRIORITY - - PDMA_HIGH_PRIORITY - One of the following to specify the transfer size: - - PDMA_BYTE_TRANSFER - - PDMA_HALFWORD_TRANSFER - - PDMA_WORD_TRANSFER - One or two of the following to specify the source and/or destination address - increment: - - PDMA_NO_INC - - PDMA_INC_SRC_ONE_BYTE - - PDMA_INC_SRC_TWO_BYTES - - PDMA_INC_SRC_FOUR_BYTES - - PDMA_INC_DEST_ONE_BYTE - - PDMA_INC_DEST_TWO_BYTES - - PDMA_INC_DEST_FOUR_BYTES - - @param write_adjust - The write_adjust parameter specifies the number of Cortex-M3 clock cycles - the PDMA controller will wait before attempting another transfer cycle. This - delay is necessary when peripherals are used as destination of a DMA transfer - to ensure the DMA controller interprets the state of the peripheral’s ready - signal only after data has actually been written to the peripheral. This delay - accounts for posted writes (dump and run) for write accesses to peripherals. - The effect of posted writes is that if the PDMA performs a write operation to - a peripheral, the data is not actually written into the peripheral until - sometime after the PDMA controller thinks it is written. - A suitable value for write_adjust depends on the target of the DMA transfer. - Guidelines for choosing this value are as follows: - • The PDMA_DEFAULT_WRITE_ADJ constant provides a suitable default value - for the write_adjust parameter when the PDMA channel is configured for - transfers with MSS peripherals. - • The PDMA_DEFAULT_WRITE_ADJ constant can also be used for DMA transfers - with FPGA fabric implemented peripherals making use of the DMAREADY0 or - DMAREADY1fabric interface signal to indicate that the peripheral is - ready for another DMA transfer. - • The write_adjust parameter can be set to zero to achieve maximum transfer - speed for genuine memory to memory transfers. - • The internal latency of FPGA implemented peripherals will decide the - write_adjust value for fabric peripherals that do not use the DMAREADY0 - or DMAREADY1 fabric interface signals. You need to check the fabric - peripheral documentation for the value to use. - - Example: - @code - PDMA_configure - ( - PDMA_CHANNEL_0, - PDMA_TO_SPI_1, - PDMA_LOW_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_SRC_ONE_BYTE, - PDMA_DEFAULT_WRITE_ADJ - ); - @endcode - */ -void PDMA_configure -( - pdma_channel_id_t channel_id, - pdma_src_dest_t src_dest, - uint32_t channel_cfg, - uint8_t write_adjust -); - - -/***************************************************************************//** - The PDMA_set_priority_ratio() function sets the ratio of high priority to low - priority DMA access opportunities. This ratio is used by the PDMA controller - arbiter to decide which PDMA channel will be given the opportunity to perform - a transfer when multiple PDMA channels are requesting to transfer data at the - same time. The priority ratio specifies how many DMA transfer opportunities - will be given to high priority channels before a DMA transfer opportunity is - given to a low priority channel when there are continuous requests from high - priority channels. - - @param priority_ratio - The priority_ratio parameter specifies the ratio of DMA access opportunities - given to high priority channels versus low priority channels. - Allowed values for this parameter are: - - PDMA_ROUND_ROBIN - - PDMA_RATIO_HIGH_LOW_1_TO_1 - - PDMA_RATIO_HIGH_LOW_3_TO_1 - - PDMA_RATIO_HIGH_LOW_7_TO_1 - - PDMA_RATIO_HIGH_LOW_15_TO_1 - - PDMA_RATIO_HIGH_LOW_31_TO_1 - - PDMA_RATIO_HIGH_LOW_63_TO_1 - - PDMA_RATIO_HIGH_LOW_127_TO_1 - - PDMA_RATIO_HIGH_LOW_255_TO_1 - - Example: - @code - PDMA_set_priority_ratio( PDMA_ROUND_ROBIN ); - @endcode - */ -static __INLINE void PDMA_set_priority_ratio -( - pdma_priority_ratio_t priority_ratio -) -{ - PDMA->RATIO_HIGH_LOW = (uint32_t)priority_ratio; -} - -/***************************************************************************//** - The PDMA_start() function initiates a DMA transfer. It specifies the source - and destination address of the transfer as well as the number of transfers - that must take place. The source and destination addresses can be the address - of peripheral registers. - - @param channel_id - The channel_id parameter identifies the PDMA channel used by the function. - - @param src_addr - The src_addr parameter specifies the address location of the data to be - transferred. You must ensure that this source address is consistent with the - DMA source configured for the selected channel using the PDMA_configure() - function. - For DMA transfers from MSS peripheral to memory, the following src_addr - parameter values are allowed: - • PDMA_SPI0_RX_REGISTER - • PDMA_SPI1_RX_REGISTER - • PDMA_UART0_RX_REGISTER - • PDMA_UART1_RX_REGISTER - • PDMA_ACE_PPE_DATAOUT - For DMA transfers from FPGA fabric peripheral to memory, the following - src_addr parameter values are allowed: - • An address in the FPGA fabric address space (0x40050000-0x400FFFFF) - For DMA transfers from memory to MSS peripheral, or from memory to FPGA - fabric peripheral, or from memory to memory, the following src_addr - parameter values are allowed: - • Any memory mapped address. - - @param dest_addr - The dest_addr parameter specifies the destination address of the PDMA - transfer. You must ensure that this matches with the DMA destination - configured for the selected channel. - For DMA transfers from memory to MSS peripheral, the following dest_addr parameter values are allowed: - • PDMA_SPI0_TX_REGISTER - • PDMA_SPI1_TX_REGISTER - • PDMA_UART0_TX_REGISTER - • PDMA_UART1_TX_REGISTER - • PDMA_ACE_SSE_DATAIN - For DMA transfers from memory to FPGA fabric peripheral, the following - dest_addr parameter values are allowed: - • An address in the FPGA fabric address space (0x40050000-0x400FFFFF) - For DMA transfers from MSS peripheral to memory, or from FPGA fabric - peripheral to memory, or from memory to memory, the following dest_addr - parameter values are allowed: - • Any memory mapped address. - - @param transfer_count - The transfer_count parameter specifies the number of transfers to be - performed. It is the number of bytes to transfer if the PDMA channel is - configured for byte transfer, the number of half-words to transfer if the - PDMA channel is configured for half-word transfer, or the number of words - to transfer if the PDMA channel is configured for word transfer. - - Example: - @code - PDMA_start - ( - PDMA_CHANNEL_3, - PDMA_SPI1_RX_REGISTER, - (uint32_t)slave_rx_buffer, - sizeof(slave_rx_buffer) - ); - @endcode - */ -void PDMA_start -( - pdma_channel_id_t channel_id, - uint32_t src_addr, - uint32_t dest_addr, - uint16_t transfer_count -); - -/***************************************************************************//** - The PDMA_load_next_buffer() function sets the next buffer to be transferred. - This function is called after a transfer has been initiated using the - PDMA_start() function. Its purpose is to keep feeding a PDMA channel with data - buffers. - - @param channel_id - The channel_id parameter identifies the PDMA channel used by the function. - - @param src_addr - The src_addr parameter specifies the address location of the data to be - transferred. You must ensure that this source address is consistent with the - DMA source configured for the selected channel using the PDMA_configure() - function. - For DMA transfers from MSS peripheral to memory, the following src_addr parameter values are allowed: - • PDMA_SPI0_RX_REGISTER - • PDMA_SPI1_RX_REGISTER - • PDMA_UART0_RX_REGISTER - • PDMA_UART1_RX_REGISTER - • PDMA_ACE_PPE_DATAOUT - For DMA transfers from FPGA fabric peripheral to memory, the following src_addr parameter values are allowed: - • An address in the FPGA fabric address space (0x40050000-0x400FFFFF) - For DMA transfers from memory to MSS peripheral, or from memory to FPGA fabric peripheral, or from memory to memory, the following src_addr parameter values are allowed: - • Any memory mapped address. - - @param dest_addr - The dest_addr parameter specifies the destination address of the PDMA - transfer. You must ensure that this matches with the DMA destination - configured for the selected channel. - For DMA transfers from memory to MSS peripheral, the following dest_addr parameter values are allowed: - • PDMA_SPI0_TX_REGISTER - • PDMA_SPI1_TX_REGISTER - • PDMA_UART0_TX_REGISTER - • PDMA_UART1_TX_REGISTER - • PDMA_ACE_SSE_DATAIN - For DMA transfers from memory to FPGA fabric peripheral, the following dest_addr parameter values are allowed: - • An address in the FPGA fabric address space (0x40050000-0x400FFFFF) - For DMA transfers from MSS peripheral to memory, or from FPGA fabric peripheral to memory, or from memory to memory, the following dest_addr parameter values are allowed: - • Any memory mapped address. - - @param transfer_count - The transfer_count parameter specifies the number of transfers to be - performed. It is the number of bytes to transfer if the PDMA channel is - configured for byte transfer, the number of half-words to transfer if the - PDMA channel is configured for half-word transfer or the number of words to - transfer if the PDMA channel is configured for word transfer. - - Example: - @code - void write_cmd_data - ( - mss_spi_instance_t * this_spi, - const uint8_t * cmd_buffer, - uint16_t cmd_byte_size, - uint8_t * data_buffer, - uint16_t data_byte_size - ) - { - uint32_t transfer_size; - - transfer_size = cmd_byte_size + data_byte_size; - - MSS_SPI_disable( this_spi ); - MSS_SPI_set_transfer_byte_count( this_spi, transfer_size ); - - PDMA_start - ( - PDMA_CHANNEL_0, - (uint32_t)cmd_buffer, - PDMA_SPI1_TX_REGISTER, - cmd_byte_size - ); - - PDMA_load_next_buffer - ( - PDMA_CHANNEL_0, - (uint32_t)data_buffer, - PDMA_SPI1_TX_REGISTER, - data_byte_size - ); - - MSS_SPI_enable( this_spi ); - - while ( !MSS_SPI_tx_done(this_spi) ) - { - ; - } - } - @endcode - */ -void PDMA_load_next_buffer -( - pdma_channel_id_t channel_id, - uint32_t src_addr, - uint32_t dest_addr, - uint16_t transfer_count -); - -/***************************************************************************//** - The PDMA_status() function returns the status of a DMA channel. - The returned value indicates if transfers have been completed using buffer A - or buffer B of the PDMA hardware block. - - @param channel_id - The channel_id parameter identifies the PDMA channel used by the function. - - @return - bit 0 of the return value indicates if buffer A has been trasnfered. It is - set to 1 if the transfer has completed. - bit 1 of the return value indicates if buffer B has been transfered. It is - set to 1 if the transfer has completed. - */ -uint32_t PDMA_status -( - pdma_channel_id_t channel_id -); - -/***************************************************************************//** - The PDMA_pause() function temporarily pauses a PDMA transfer taking place on - the specified PDMA channel. The transfer can later be resumed by using the - PDMA_resume() function. - - @param channel_id - The channel_id parameter identifies the PDMA channel used by the function. - */ -static __INLINE void PDMA_pause( pdma_channel_id_t channel_id ) -{ - PDMA->CHANNEL[channel_id].CRTL |= PDMA_PAUSE_MASK; -} - -/***************************************************************************//** - The PDMA_resume() function resumes a transfer previously paused using the - PDMA_pause() function. - - @param channel_id The channel_id parameter identifies the PDMA channel - used by the function. - */ -static __INLINE void PDMA_resume( pdma_channel_id_t channel_id ) -{ - PDMA->CHANNEL[channel_id].CRTL &= ~PDMA_PAUSE_MASK; -} - -/***************************************************************************//** - The PDMA_enable_irq() enables the PDMA hardware to generate an interrupt when - a DMA transfer completes on the specified PDMA channel. This function also - enables the PDMA interrupt in the Cortex-M3 interrupt controller. - - @param channel_id - The channel_id parameter identifies the PDMA channel used by the function. - */ -void PDMA_enable_irq( pdma_channel_id_t channel_id ); - -/***************************************************************************//** - The PDMA_disable_irq() disables interrupts for a specific PDMA channel. - - @param channel_id - The channel_id parameter identifies the PDMA channel used by the function. - */ -static __INLINE void PDMA_disable_irq( pdma_channel_id_t channel_id ) -{ - PDMA->CHANNEL[channel_id].CRTL &= ~PDMA_IRQ_ENABLE_MASK; -} - -/***************************************************************************//** - The PDMA_set_irq_handler() function registers a handler function for - interrupts generated on the completion of a transfer on a specific PDMA - channel. This function also enables the PDMA interrupt both in the PDMA - controller and in the Cortex-M3 interrupt controller. - - @param channel_id - The channel_id parameter identifies the PDMA channel used by the function. - - @param handler - The handler parameter is a pointer to the function that will be called when - a transfer completes on the PDMA channel identified by channel_id and the - interrupt is enabled for that channel. - - Example: - @code - void slave_dma_irq_handler( void ) - { - if ( g_spi1_rx_buffer[2] == 0x99 ) - { - PDMA_load_next_buffer - ( - PDMA_CHANNEL_0, - (uint32_t)g_spi1_tx_buffer_b, - PDMA_SPI1_TX_REGISTER, - sizeof(g_spi1_tx_buffer_b) - ); - } - PDMA_disable_irq( PDMA_CHANNEL_3 ); - } - - void setup_dma( void ) - { - PDMA_init(); - PDMA_configure - ( - PDMA_CHANNEL_0, - PDMA_TO_SPI_1, - PDMA_LOW_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_SRC_ONE_BYTE - ); - PDMA_configure - ( - PDMA_CHANNEL_3, - PDMA_FROM_SPI_1, - PDMA_HIGH_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_DEST_ONE_BYTE - ); - PDMA_set_irq_handler( PDMA_CHANNEL_3, slave_dma_irq_handler ); - PDMA_start( PDMA_CHANNEL_3, PDMA_SPI1_RX_REGISTER, (uint32_t)g_spi1_rx_buffer, 3 ); - } - @endcode - */ -void PDMA_set_irq_handler -( - pdma_channel_id_t channel_id, - pdma_channel_isr_t handler -); - -/***************************************************************************//** - The PDMA_clear_irq() function clears interrupts for a specific PDMA channel. - This function also clears the PDMA interrupt in the Cortex-M3 NVIC. - - @param channel_id - The channel_id parameter identifies the PDMA channel used by the function. - */ -void PDMA_clear_irq -( - pdma_channel_id_t channel_id -); - -#ifdef __cplusplus -} -#endif - -#endif /* __MSS_PERIPHERAL_DMA_H_ */ diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.c deleted file mode 100644 index e5992301f..000000000 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.c +++ /dev/null @@ -1,610 +0,0 @@ -/******************************************************************************* - * (c) Copyright 2008 Actel Corporation. All rights reserved. - * - * SmartFusion microcontroller subsystem SPI bare metal software driver - * implementation. - * - * SVN $Revision: 2176 $ - * SVN $Date: 2010-02-15 21:04:22 +0000 (Mon, 15 Feb 2010) $ - */ -#include "mss_spi.h" -#include "../../CMSIS/mss_assert.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************//** - MSS SPI can operate as master or slave. - */ -#define MSS_SPI_MODE_SLAVE (uint32_t)0 -#define MSS_SPI_MODE_MASTER (uint32_t)1 - -/***************************************************************************//** - * Mask of transfer protocol and SPO, SPH bits within control register. - */ -#define PROTOCOL_MODE_MASK (uint32_t)0x030000C0 - -/***************************************************************************//** - * Mask of theframe count bits within the SPI control register. - */ -#define TXRXDFCOUNT_MASK (uint32_t)0x00FFFF00 -#define TXRXDFCOUNT_SHIFT (uint32_t)8 - -/***************************************************************************//** - * SPI hardware FIFO depth. - */ -#define RX_FIFO_SIZE 4u - -/***************************************************************************//** - Marker used to detect that the configuration has not been selected for a - specific slave when operating as a master. - */ -#define NOT_CONFIGURED 0xFFFFFFFF - -/***************************************************************************//** - * SPI instance data structures for SPI0 and SPI1. A pointer to these data - * structures must be used as first parameter to any of the SPI driver functions - * to identify the SPI hardware block that will perform the requested operation. - */ -mss_spi_instance_t g_mss_spi0; -mss_spi_instance_t g_mss_spi1; - -/***************************************************************************//** - SPI0 interrupt service routine - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void SPI0_IRQHandler( void ); -#else -void SPI0_IRQHandler( void ); -#endif - -/***************************************************************************//** - SPI1 interrupt service routine - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void SPI1_IRQHandler( void ); -#else -void SPI1_IRQHandler( void ); -#endif - -/***************************************************************************//** - * MSS_SPI_init() - * See "mss_spi.h" for details of how to use this function. - */ -void MSS_SPI_init -( - mss_spi_instance_t * this_spi -) -{ - uint16_t i; - - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - - if (this_spi == &g_mss_spi0) - { - this_spi->hw_reg = SPI0; - this_spi->hw_reg_bit = SPI0_BITBAND; - this_spi->irqn = SPI0_IRQn; - - /* reset SPI0 */ - SYSREG->SOFT_RST_CR |= SYSREG_SPI0_SOFTRESET_MASK; - /* Clear any previously pended SPI0 interrupt */ - NVIC_ClearPendingIRQ( SPI0_IRQn ); - /* Take SPI0 out of reset. */ - SYSREG->SOFT_RST_CR &= ~SYSREG_SPI0_SOFTRESET_MASK; - } - else - { - this_spi->hw_reg = SPI1; - this_spi->hw_reg_bit = SPI1_BITBAND; - this_spi->irqn = SPI1_IRQn; - - /* reset SPI1 */ - SYSREG->SOFT_RST_CR |= SYSREG_SPI1_SOFTRESET_MASK; - /* Clear any previously pended SPI1 interrupt */ - NVIC_ClearPendingIRQ( SPI1_IRQn ); - /* Take SPI1 out of reset. */ - SYSREG->SOFT_RST_CR &= ~SYSREG_SPI1_SOFTRESET_MASK; - } - - this_spi->frame_rx_handler = 0U; - this_spi->slave_tx_frame = 0U; - - this_spi->block_rx_handler = 0U; - - this_spi->slave_tx_buffer = 0U; - this_spi->slave_tx_size = 0U; - this_spi->slave_tx_idx = 0U; - - for ( i = 0u; i < (uint16_t)MSS_SPI_MAX_NB_OF_SLAVES; ++i ) - { - this_spi->slaves_cfg[i].ctrl_reg = NOT_CONFIGURED; - } -} - -/***************************************************************************//** - * MSS_SPI_configure_slave_mode() - * See "mss_spi.h" for details of how to use this function. - */ -void MSS_SPI_configure_slave_mode -( - mss_spi_instance_t * this_spi, - mss_spi_protocol_mode_t protocol_mode, - mss_spi_pclk_div_t clk_rate, - uint8_t frame_bit_length -) -{ - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - ASSERT( frame_bit_length <= 32 ); - - /* Set the mode. */ - this_spi->hw_reg_bit->CTRL_MASTER = MSS_SPI_MODE_SLAVE; - - /* Set the clock rate. */ - this_spi->hw_reg_bit->CTRL_ENABLE = 0U; - this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~PROTOCOL_MODE_MASK) | (uint32_t)protocol_mode; - this_spi->hw_reg->CLK_GEN = (uint32_t)clk_rate; - - /* Set default frame size to byte size and number of data frames to 1. */ - this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | ((uint32_t)1 << TXRXDFCOUNT_SHIFT); - this_spi->hw_reg->TXRXDF_SIZE = frame_bit_length; - this_spi->hw_reg_bit->CTRL_ENABLE = 1U; -} - -/***************************************************************************//** - * MSS_SPI_configure_master_mode() - * See "mss_spi.h" for details of how to use this function. - */ -void MSS_SPI_configure_master_mode -( - mss_spi_instance_t * this_spi, - mss_spi_slave_t slave, - mss_spi_protocol_mode_t protocol_mode, - mss_spi_pclk_div_t clk_rate, - uint8_t frame_bit_length -) -{ - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - ASSERT( slave < MSS_SPI_MAX_NB_OF_SLAVES ); - ASSERT( frame_bit_length <= 32 ); - - /* Set the mode. */ - this_spi->hw_reg_bit->CTRL_ENABLE = 0U; - this_spi->hw_reg_bit->CTRL_MASTER = MSS_SPI_MODE_MASTER; - this_spi->hw_reg_bit->CTRL_ENABLE = 1U; - - /* - * Keep track of the required register configuration for this slave. These - * values will be used by the MSS_SPI_set_slave_select() function to configure - * the master to match the slave being selected. - */ - if ( slave < MSS_SPI_MAX_NB_OF_SLAVES ) - { - this_spi->slaves_cfg[slave].ctrl_reg = 0x00000002uL | (uint32_t)protocol_mode | ((uint32_t)1 << TXRXDFCOUNT_SHIFT); - this_spi->slaves_cfg[slave].txrxdf_size_reg = frame_bit_length; - this_spi->slaves_cfg[slave].clk_gen = (uint8_t)clk_rate; - } -} - -/***************************************************************************//** - * MSS_SPI_set_slave_select() - * See "mss_spi.h" for details of how to use this function. - */ -void MSS_SPI_set_slave_select -( - mss_spi_instance_t * this_spi, - mss_spi_slave_t slave -) -{ - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - - /* This function is only intended to be used with an SPI master. */ - ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER ); - ASSERT( this_spi->slaves_cfg[slave].ctrl_reg != NOT_CONFIGURED ); - - /* Set the clock rate. */ - this_spi->hw_reg_bit->CTRL_ENABLE = 0U; - this_spi->hw_reg->CONTROL = this_spi->slaves_cfg[slave].ctrl_reg; - this_spi->hw_reg->CLK_GEN = this_spi->slaves_cfg[slave].clk_gen; - this_spi->hw_reg->TXRXDF_SIZE = this_spi->slaves_cfg[slave].txrxdf_size_reg; - this_spi->hw_reg_bit->CTRL_ENABLE = 1U; - - /* Set slave select */ - this_spi->hw_reg->SLAVE_SELECT |= ((uint32_t)1 << (uint32_t)slave); -} - -/***************************************************************************//** - * MSS_SPI_clear_slave_select() - * See "mss_spi.h" for details of how to use this function. - */ -void MSS_SPI_clear_slave_select -( - mss_spi_instance_t * this_spi, - mss_spi_slave_t slave -) -{ - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - - /* This function is only intended to be used with an SPI master. */ - ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER ); - - this_spi->hw_reg->SLAVE_SELECT &= ~((uint32_t)1 << (uint32_t)slave); -} - -/***************************************************************************//** - * MSS_SPI_transfer_frame() - * See "mss_spi.h" for details of how to use this function. - */ -uint32_t MSS_SPI_transfer_frame -( - mss_spi_instance_t * this_spi, - uint32_t tx_bits -) -{ - volatile uint32_t dummy; - - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - - /* This function is only intended to be used with an SPI master. */ - ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER ); - - /* Flush Rx FIFO. */ - while ( this_spi->hw_reg_bit->STATUS_RX_RDY == 1U ) - { - dummy = this_spi->hw_reg->RX_DATA; - dummy = dummy; /* Prevent Lint warning. */ - } - - /* Send frame. */ - this_spi->hw_reg->TX_DATA = tx_bits; - - /* Wait for frame Tx to complete. */ - while ( this_spi->hw_reg_bit->STATUS_TX_DONE == 0U ) - { - ; - } - - /* Read received frame. */ - /* Wait for Rx complete. */ - while ( this_spi->hw_reg_bit->STATUS_RX_RDY == 0U ) - { - ; - } - /* Return Rx data. */ - return( this_spi->hw_reg->RX_DATA ); -} - - -/***************************************************************************//** - * MSS_SPI_transfer_block() - * See "mss_spi.h" for details of how to use this function. - */ -void MSS_SPI_transfer_block -( - mss_spi_instance_t * this_spi, - const uint8_t * cmd_buffer, - uint16_t cmd_byte_size, - uint8_t * rd_buffer, - uint16_t rd_byte_size -) -{ - uint16_t transfer_idx = 0U; - uint16_t tx_idx; - uint16_t rx_idx; - uint32_t frame_count; - volatile uint32_t rx_raw; - uint16_t transit = 0U; - - uint16_t transfer_size; /* Total number of bytes transfered. */ - - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - - /* This function is only intended to be used with an SPI master. */ - ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_MASTER ); - - /* Compute number of bytes to transfer. */ - transfer_size = cmd_byte_size + rd_byte_size; - - /* Adjust to 1 byte transfer to cater for DMA transfers. */ - if ( transfer_size == 0U ) - { - frame_count = 1U; - } - else - { - frame_count = transfer_size; - } - - /* Set frame size to 8 bits and the frame count to the tansfer size. */ - this_spi->hw_reg_bit->CTRL_ENABLE = 0U; - this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | ( (frame_count << TXRXDFCOUNT_SHIFT) & TXRXDFCOUNT_MASK); - this_spi->hw_reg->TXRXDF_SIZE = 8U; - this_spi->hw_reg_bit->CTRL_ENABLE = 1U; - - /* Flush the receive FIFO. */ - while ( !this_spi->hw_reg_bit->STATUS_RX_FIFO_EMPTY ) - { - rx_raw = this_spi->hw_reg->RX_DATA; - } - - tx_idx = 0u; - rx_idx = 0u; - if ( tx_idx < cmd_byte_size ) - { - this_spi->hw_reg->TX_DATA = cmd_buffer[tx_idx]; - ++tx_idx; - ++transit; - } - else - { - if ( tx_idx < transfer_size ) - { - this_spi->hw_reg->TX_DATA = 0x00U; - ++tx_idx; - ++transit; - } - } - /* Perform the remainder of the transfer by sending a byte every time a byte - * has been received. This should ensure that no Rx overflow can happen in - * case of an interrupt occurs during this function. */ - while ( transfer_idx < transfer_size ) - { - if ( !this_spi->hw_reg_bit->STATUS_RX_FIFO_EMPTY ) - { - /* Process received byte. */ - rx_raw = this_spi->hw_reg->RX_DATA; - if ( transfer_idx >= cmd_byte_size ) - { - if ( rx_idx < rd_byte_size ) - { - rd_buffer[rx_idx] = (uint8_t)rx_raw; - } - ++rx_idx; - } - ++transfer_idx; - --transit; - } - - if ( !this_spi->hw_reg_bit->STATUS_TX_FIFO_FULL ) - { - if (transit < RX_FIFO_SIZE) - { - /* Send another byte. */ - if ( tx_idx < cmd_byte_size ) - { - this_spi->hw_reg->TX_DATA = cmd_buffer[tx_idx]; - ++tx_idx; - ++transit; - } - else - { - if ( tx_idx < transfer_size ) - { - this_spi->hw_reg->TX_DATA = 0x00U; - ++tx_idx; - ++transit; - } - } - } - } - } -} - -/***************************************************************************//** - * MSS_SPI_set_frame_rx_handler() - * See "mss_spi.h" for details of how to use this function. - */ -void MSS_SPI_set_frame_rx_handler -( - mss_spi_instance_t * this_spi, - mss_spi_frame_rx_handler_t rx_handler -) -{ - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - - /* This function is only intended to be used with an SPI slave. */ - ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_SLAVE ); - - /* Disable block Rx handler as they are mutually exclusive. */ - this_spi->block_rx_handler = 0U; - - /* Keep a copy of the pointer to the rx hnadler function. */ - this_spi->frame_rx_handler = rx_handler; - - /* Enable Rx interrupt. */ - this_spi->hw_reg_bit->CTRL_RX_INT_EN = 1U; - NVIC_EnableIRQ( this_spi->irqn ); -} - -/***************************************************************************//** - * MSS_SPI_set_slave_tx_frame() - * See "mss_spi.h" for details of how to use this function. - */ -void MSS_SPI_set_slave_tx_frame -( - mss_spi_instance_t * this_spi, - uint32_t frame_value -) -{ - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - - /* This function is only intended to be used with an SPI slave. */ - ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_SLAVE ); - - /* Disable slave block tx buffer as it is mutually exclusive with frame - * level handling. */ - this_spi->slave_tx_buffer = 0U; - this_spi->slave_tx_size = 0U; - this_spi->slave_tx_idx = 0U; - - /* Keep a copy of the slave tx frame value. */ - this_spi->slave_tx_frame = frame_value; - - /* Load frame into Tx data register. */ - this_spi->hw_reg->TX_DATA = this_spi->slave_tx_frame; - - /* Enable Tx Done interrupt in order to reload the slave Tx frame after each - * time it has been sent. */ - this_spi->hw_reg_bit->CTRL_TX_INT_EN = 1U; - NVIC_EnableIRQ( this_spi->irqn ); -} - -/***************************************************************************//** - * MSS_SPI_set_slave_block_buffers() - * See "mss_spi.h" for details of how to use this function. - */ -void MSS_SPI_set_slave_block_buffers -( - mss_spi_instance_t * this_spi, - const uint8_t * tx_buffer, - uint32_t tx_buff_size, - uint8_t * rx_buffer, - uint32_t rx_buff_size, - mss_spi_block_rx_handler_t block_rx_handler -) -{ - uint32_t frame_count; - - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - - /* This function is only intended to be used with an SPI slave. */ - ASSERT( this_spi->hw_reg_bit->CTRL_MASTER == MSS_SPI_MODE_SLAVE ); - - /* Disable Rx frame handler as it is mutually exclusive with block rx handler. */ - this_spi->frame_rx_handler = 0U; - - /* Keep a copy of the pointer to the block rx handler function. */ - this_spi->block_rx_handler = block_rx_handler; - - this_spi->slave_rx_buffer = rx_buffer; - this_spi->slave_rx_size = rx_buff_size; - this_spi->slave_rx_idx = 0U; - - /**/ - this_spi->slave_tx_buffer = tx_buffer; - this_spi->slave_tx_size = tx_buff_size; - this_spi->slave_tx_idx = 0U; - - frame_count = rx_buff_size; - - /**/ - this_spi->hw_reg_bit->CTRL_ENABLE = 0U; - this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | (frame_count << TXRXDFCOUNT_SHIFT); - this_spi->hw_reg->TXRXDF_SIZE = 8U; - this_spi->hw_reg_bit->CTRL_ENABLE = 1U; - - /* Load the transmit FIFO. */ - while ( !(this_spi->hw_reg_bit->STATUS_TX_FIFO_FULL) && ( this_spi->slave_tx_idx < this_spi->slave_tx_size ) ) - { - this_spi->hw_reg->TX_DATA = this_spi->slave_tx_buffer[this_spi->slave_tx_idx]; - ++this_spi->slave_tx_idx; - } - - /* Enable Rx interrupt. */ - this_spi->hw_reg_bit->CTRL_RX_INT_EN = 1U; - NVIC_EnableIRQ( this_spi->irqn ); -} - -/***************************************************************************//** - * SPI interrupt service routine. - */ -static void mss_spi_isr -( - mss_spi_instance_t * this_spi -) -{ - uint32_t rx_frame; - - ASSERT( (this_spi == &g_mss_spi0) || (this_spi == &g_mss_spi1) ); - - if ( this_spi->hw_reg_bit->MIS_RX_RDY ) - { - while( !this_spi->hw_reg_bit->STATUS_RX_FIFO_EMPTY ) - { - rx_frame = this_spi->hw_reg->RX_DATA; - if ( this_spi->frame_rx_handler != 0U ) - { - /* Single frame handling mode. */ - this_spi->frame_rx_handler( rx_frame ); - } - else - { - if ( this_spi->block_rx_handler != 0U ) - { - /* Block handling mode. */ - if ( this_spi->slave_rx_idx < this_spi->slave_rx_size ) - { - this_spi->slave_rx_buffer[this_spi->slave_rx_idx] = (uint8_t)rx_frame; - ++this_spi->slave_rx_idx; - if ( this_spi->slave_rx_idx == this_spi->slave_rx_size ) - { - (*this_spi->block_rx_handler)( this_spi->slave_rx_buffer, this_spi->slave_rx_size ); - } - } - } - } - - /* Feed transmit FIFO. */ - if ( !(this_spi->hw_reg_bit->STATUS_TX_FIFO_FULL) && ( this_spi->slave_tx_idx < this_spi->slave_tx_size ) ) - { - this_spi->hw_reg->TX_DATA = this_spi->slave_tx_buffer[this_spi->slave_tx_idx]; - ++this_spi->slave_tx_idx; - } - } - this_spi->hw_reg_bit->INT_CLEAR_RX_RDY = 1U; - } - - if ( this_spi->hw_reg_bit->MIS_TX_DONE ) - { - if ( this_spi->slave_tx_buffer != 0U ) - { - this_spi->hw_reg->TX_DATA = this_spi->slave_tx_buffer[this_spi->slave_tx_idx]; - ++this_spi->slave_tx_idx; - if ( this_spi->slave_tx_idx >= this_spi->slave_tx_size ) - { - this_spi->slave_tx_idx = 0U; - } - } - else - { - /* Reload slave tx frame into Tx data register. */ - this_spi->hw_reg->TX_DATA = this_spi->slave_tx_frame; - } - } -} - -/***************************************************************************//** - * SPIO interrupt service routine. - * Please note that the name of this ISR is defined as part of the SmartFusion - * CMSIS startup code. - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void SPI0_IRQHandler( void ) -#else -void SPI0_IRQHandler( void ) -#endif -{ - mss_spi_isr( &g_mss_spi0 ); - NVIC_ClearPendingIRQ( SPI0_IRQn ); -} - -/***************************************************************************//** - * SPI1 interrupt service routine. - * Please note that the name of this ISR is defined as part of the SmartFusion - * CMSIS startup code. - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void SPI1_IRQHandler( void ) -#else -void SPI1_IRQHandler( void ) -#endif -{ - mss_spi_isr( &g_mss_spi1 ); - NVIC_ClearPendingIRQ( SPI1_IRQn ); -} - -#ifdef __cplusplus -} -#endif - diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.h deleted file mode 100644 index 2b3617bc4..000000000 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_spi/mss_spi.h +++ /dev/null @@ -1,1296 +0,0 @@ -/***************************************************************************//** - * (c) Copyright 2008 Actel Corporation. All rights reserved. - * - * SmartFusion microcontroller subsystem SPI bare metal software driver public API. - * - * The microcontroller subsystem SPI driver provides functions for implementing - * SPI master or SPI slave operations. These operations can be one of two - * classes: SPI frame operation or block transfer operations. - * Frame operations allow transferring SPI frames from 4 to 32 bits long. Block - * operations allow transferring blocks of data organized as 8 bit bytes. - * - * SVN $Revision: 2189 $ - * SVN $Date: 2010-02-16 22:02:32 +0000 (Tue, 16 Feb 2010) $ - */ -/*=========================================================================*//** - @mainpage SmartFusion MSS SPI Bare Metal Driver. - - @section intro_sec Introduction - The SmartFusion™ microcontroller subsystem (MSS) includes two serial - peripheral interface SPI peripherals for serial communication. This driver - provides a set of functions for controlling the MSS SPIs as part of a bare - metal system where no operating system is available. These drivers can be - adapted for use as part of an operating system, but the implementation of the - adaptation layer between this driver and the operating system's driver model - is outside the scope of this driver. - - @section hw_dependencies Hardware Flow Dependencies - The configuration of all features of the MSS SPIs is covered by this driver - with the exception of the SmartFusion IOMUX configuration. SmartFusion allows - multiple non-concurrent uses of some external pins through IOMUX configuration. - This feature allows optimization of external pin usage by assigning external - pins for use by either the microcontroller subsystem or the FPGA fabric. The - MSS SPIs serial signals are routed through IOMUXes to the SmartFusion device - external pins. These IOMUXes are automatically configured correctly by the MSS - configurator tool in the hardware flow when the MSS SPIs are enabled in that - tool. You must ensure that the MSS SPIs are enabled by the MSS configurator - tool in the hardware flow; otherwise the serial inputs and outputs will not be - connected to the chip's external pins. For more information on IOMUX, refer to - the IOMUX section of the SmartFusion Datasheet. - The base address, register addresses and interrupt number assignment for the - MSS SPI blocks are defined as constants in the SmartFusion CMSIS-PAL. You must - ensure that the SmartFusion CMSIS-PAL is either included in the software tool - chain used to build your project or is included in your project. - - @section theory_op Theory of Operation - The MSS SPI driver functions are grouped into the following categories: - • Initialization - • Configuration for either master or slave operations - • SPI master frame transfer control - • SPI master block transfer control - • SPI slave frame transfer control - • SPI slave block transfer control - • DMA block transfer - Frame transfers allow the MSS SPI to write or read up to 32 bits of data in a - SPI transaction. For example, a frame transfer of 12 bits might be used to - read the result of an ADC conversion from a SPI analog to digital converter. - Block transfers allow the MSS SPI to write or read a number of bytes in a SPI - transaction. Block transfer transactions allow data transfers in multiples of - 8 bits (8, 16, 24, 32, 40…). Block transfers are typically used with byte - oriented devices like SPI FLASH devices. - - Initialization - The MSS SPI driver is initialized through a call to the MSS_SPI_init() - function. The MSS_SPI_init() function takes only one parameter, a pointer - to one of two global data structures used by the driver to store state - information for each MSS SPI. A pointer to these data structures is also - used as first parameter to any of the driver functions to identify which MSS - SPI will be used by the called function. The names of these two data - structures are g_mss_spi0 and g_mss_spi1. Therefore any call to an MSS SPI - driver function should be of the form MSS_SPI_function_name( &g_mss_spi0, ... ) - or MSS_SPI_function_name( &g_mss_spi1, ... ). - The MSS_SPI_init() function resets the specified MSS SPI hardware block and - clears any pending interrupts from that MSS SPI in the Cortex-M3 NVIC. - The MSS_SPI_init() function must be called before any other MSS SPI driver - functions can be called. - - Configuration - A MSS SPI block can operate either as a master or slave SPI device. There - are two distinct functions for configuring a MSS SPI block for master or - slave operations. - - Master configuration - The MSS_SPI_configure_master_mode() function configures the specified MSS - SPI block for operations as a SPI master. It must be called once for each - remote SPI slave device the MSS SPI block will communicate with. It is used - to provide the following information about each SPI slave’s communication - characteristics: - • The SPI protocol mode - • The SPI clock speed - • The frame bit length - This information is held by the driver and will be used to alter the - configuration of the MSS SPI block each time a slave is selected through a - call to MSS_SPI_set_slave_select(). The SPI protocol mode defines the - initial state of the clock signal at the start of a transaction and which - clock edge will be used to sample the data signal, or it defines whether the - SPI block will operate in TI synchronous serial mode or in NSC MICROWIRE mode. - - Slave configuration - The MSS_SPI_configure_slave_mode() function configures the specified MSS SPI - block for operations as a SPI slave. It configures the following SPI - communication characteristics: - • The SPI protocol mode - • The SPI clock speed - • The frame bit length - The SPI protocol mode defines the initial state of the clock signal at the - start of a transaction and which clock edge will be used to sample the data - signal, or it defines whether the SPI block will operate in TI synchronous - serial mode or in NSC MICROWIRE mode. - - SPI master frame transfer control - The following functions are used as part of SPI master frame transfers: - • MSS_SPI_set_slave_select() - • MSS_SPI_transfer_frame() - • MSS_SPI_clear_slave_select() - The master must first select the target slave through a call to - MSS_SPI_set_slave_select(). This causes the relevant slave select line to - become asserted while data is clocked out onto the SPI data line. - A call to is then made to function MSS_SPI_transfer_frame() specifying and - the value of the data frame to be sent. - The function MSS_SPI_clear_slave_select() can be used after the transfer is - complete to prevent this slave select line from being asserted during - subsequent SPI transactions. A call to this function is only required if the - master is communicating with multiple slave devices. - - SPI master block transfer control - The following functions are used as part of SPI master block transfers: - • MSS_SPI_set_slave_select() - • MSS_SPI_clear_slave_select() - • MSS_SPI_transfer_block() - The master must first select the target slave through a call to - MSS_SPI_set_slave_select(). This causes the relevant slave select line to - become asserted while data is clocked out onto the SPI data line. - Alternatively a GPIO can be used to control the state of the target slave - device’s chip select signal. - A call to is then made to function MSS_SPI_transfer_block (). The - parameters of this function specify: - • the number of bytes to be transmitted - • a pointer to the buffer containing the data to be transmitted - • the number of bytes to be received - • a pointer to the buffer where received data will be stored - The number of bytes to be transmitted can be set to zero to indicate that - the transfer is purely a block read transfer. The number of bytes to be - received can be set to zero to specify that the transfer is purely a block - write transfer. - The function MSS_SPI_clear_slave_select() can be used after the transfer is - complete to prevent this slave select line from being asserted during - subsequent SPI transactions. A call to this function is only required if the - master is communicating with multiple slave devices. - - SPI slave frame transfer control - The following functions are used as part of SPI slave frame transfers: - • MSS_SPI_set_slave_tx_frame() - • MSS_SPI_set_frame_rx_handler() - The MSS_SPI_set_slave_tx_frame() function specifies the frame data that will - be returned to the SPI master. The frame data specified through this - function is the value that will be read over the SPI bus by the remote SPI - master when it initiates a transaction. A call to MSS_SPI_set_slave_tx_frame() - is only required if the MSS SPI slave is the target of SPI read transactions, - i.e. if data is meant to be read from the SmartFusion device over SPI. - The MSS_SPI_set_frame_rx_handler() function specifies the receive handler - function that will called when a frame of data has been received by the MSS - SPI when it is configured as a slave. The receive handler function specified - through this call will process the frame data written, over the SPI bus, to - the MSS SPI slave by the remote SPI master. The receive handler function must - be implemented as part of the application. It is only required if the MSS SPI - slave is the target of SPI frame write transactions. - - SPI slave block transfer control - The following functions are used as part of SPI slave block transfers: - • MSS_SPI_set_slave_block_buffers() - The MSS_SPI_set_slave_block_buffers() function is used to configure a MSS SPI - slave for block transfer operations. It specifies: - • The buffer containing the data that will be returned to the remote SPI master - • The buffer where data received from the remote SPI master will be stored - • The handler function that will be called after the receive buffer is filled - - DMA block transfer control - The following functions are used as part of MSS SPI DMA transfers: - • MSS_SPI_disable() - • MSS_SPI_set_transfer_byte_count() - • MSS_SPI_enable() - • MSS_SPI_tx_done() - The MSS SPI must first be disabled through a call to function MSS_SPI_disable(). - The number of bytes to be transferred is then set through a call to function - MSS_SPI_set_transfer_byte_count(). The DMA transfer is then initiated by a call - to the MSS_PDMA_start() function provided by the MSS PDMA driver. The actual - DMA transfer will only start once the MSS SPI block has been re-enabled through - a call to MSS_SPI_enable(). The completion of the DMA driven SPI transfer can - be detected through a call to MSS_SPI_tx_done(). The direction of the SPI - transfer, write or read, depends on the DMA channel configuration. A SPI write - transfer occurs when the DMA channel is configured to write data to the MSS SPI - block. A SPI read transfer occurs when the DMA channel is configured to read data - from the MSS SPI block. - - *//*=========================================================================*/ -#ifndef MSS_SPI_H_ -#define MSS_SPI_H_ - -#include "../../CMSIS/a2fxxxm3.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************//** - This defines the function prototype that must be followed by MSS SPI slave - frame receive handler functions. These functions are registered with the MSS - SPI driver through the MSS_SPI_set_frame_rx_handler () function. - - Declaring and Implementing Slave Frame Receive Handler Functions: - Slave frame receive handler functions should follow the following prototype: - void slave_frame_receive_handler ( uint32_t rx_frame ); - The actual name of the receive handler is unimportant. You can use any name - of your choice for the receive frame handler. The rx_frame parameter will - contain the value of the received frame. - */ -typedef void (*mss_spi_frame_rx_handler_t)( uint32_t rx_frame ); - -/***************************************************************************//** - This defines the function prototype that must be followed by MSS SPI slave - block receive handler functions. These functions are registered with the MSS - SPI driver through the MSS_SPI_set_slave_block_buffers() function. - - Declaring and Implementing Slave Block Receive Handler Functions - Slave block receive handler functions should follow the following prototype: - void mss_spi_block_rx_handler ( uint8_t * rx_buff, uint16_t rx_size ); - The actual name of the receive handler is unimportant. You can use any name - of your choice for the receive frame handler. The rx_buff parameter will - contain a pointer to the start of the received block. The rx_size parameter - will contain the number of bytes of the received block. - - */ -typedef void (*mss_spi_block_rx_handler_t)( uint8_t * rx_buff, uint32_t rx_size ); - -/***************************************************************************//** - This enumeration is used to define the settings for the SPI protocol mode - bits, CPHA and CPOL. It is used as a parameter to the MSS_SPI_configure_master_mode() - and MSS_SPI_configure_slave_mode() functions. - - - MSS_SPI_MODE0: - Clock starts low, data read on clock's rising edge, data changes on - falling edge. - - - MSS_SPI_MODE1: - Clock starts low, data read on clock's falling edge, data changes on - rising edge. - - - MSS_SPI_MODE2: - Clock starts high, data read on clock's falling edge, data changes on - rising edge. - - - MSS_SPI_MODE3: - Clock starts high, data read on clock's rising edge, data changes on - falling edge. - - - MSS_TI_MODE: - TI syncronous serial mode. Slave select is pulsed at start of transfer. - - - MSS_NSC_MODE: - NSC Microwire mode. - */ -typedef enum __mss_spi_protocol_mode_t -{ - MSS_SPI_MODE0 = 0x00000000, - MSS_SPI_TI_MODE = 0x00000004, - MSS_SPI_NSC_MODE = 0x00000008, - MSS_SPI_MODE2 = 0x01000000, - MSS_SPI_MODE1 = 0x02000000, - MSS_SPI_MODE3 = 0x03000000 -} mss_spi_protocol_mode_t; - -/***************************************************************************//** - This enumeration specifies the divider to be applied to the the APB bus clock - in order to generate the SPI clock. It is used as parameter to the - MSS_SPI_configure_master_mode() and MSS_SPI_configure_slave_mode()functions. - */ - typedef enum __mss_spi_pclk_div_t - { - MSS_SPI_PCLK_DIV_2 = 0, - MSS_SPI_PCLK_DIV_4 = 1, - MSS_SPI_PCLK_DIV_8 = 2, - MSS_SPI_PCLK_DIV_16 = 3, - MSS_SPI_PCLK_DIV_32 = 4, - MSS_SPI_PCLK_DIV_64 = 5, - MSS_SPI_PCLK_DIV_128 = 6, - MSS_SPI_PCLK_DIV_256 = 7 -} mss_spi_pclk_div_t; - -/***************************************************************************//** - This enumeration is used to select a specific SPI slave device (0 to 7). It is - used as a parameter to the MSS_SPI_configure_master_mode(), - MSS_SPI_set_slave_select() and MSS_SPI_clear_slave_select () functions. - */ - typedef enum __mss_spi_slave_t - { - MSS_SPI_SLAVE_0 = 0, - MSS_SPI_SLAVE_1 = 1, - MSS_SPI_SLAVE_2 = 2, - MSS_SPI_SLAVE_3 = 3, - MSS_SPI_SLAVE_4 = 4, - MSS_SPI_SLAVE_5 = 5, - MSS_SPI_SLAVE_6 = 6, - MSS_SPI_SLAVE_7 = 7, - MSS_SPI_MAX_NB_OF_SLAVES = 8 -} mss_spi_slave_t; - -/***************************************************************************//** - This constant defines a frame size of 8 bits when configuring an MSS SPI to - perform block transfer data transactions. - It must be used as the value for the frame_bit_length parameter of function - MSS_SPI_configure_master_mode() when performing block transfers between the - MSS SPI master and the target SPI slave. - It must also be used as the value for the frame_bit_length parameter of - function MSS_SPI_configure_slave_mode() when performing block transfers - between the MSS SPI slave and the remote SPI master. - */ -#define MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE 8 - -/***************************************************************************//** - The mss_spi_slave_cfg_t holds the MSS SPI configuration that must be used to - communicate with a specific SPI slave. - */ -typedef struct __mss_spi_slave_cfg_t -{ - uint32_t ctrl_reg; - uint8_t txrxdf_size_reg; - uint8_t clk_gen; -} mss_spi_slave_cfg_t; - -/***************************************************************************//** - There is one instance of this structure for each of the microcontroller - subsystem's SPIs. Instances of this structure are used to identify a specific - SPI. A pointer to an instance of the mss_spi_instance_t structure is passed as - the first parameter to MSS SPI driver functions to identify which SPI should - perform the requested operation. - */ -typedef struct __mss_spi_instance_t -{ - /* CMSIS related defines identifying the SPI hardware. */ - SPI_TypeDef * hw_reg; /*!< Pointer to SPI registers. */ - SPI_BitBand_TypeDef * hw_reg_bit; /*!< Pointer to SPI registers bit band area. */ - IRQn_Type irqn; /*!< SPI's Cortex-M3 NVIC interrupt number. */ - - /* Internal transmit state: */ - const uint8_t * slave_tx_buffer; /*!< Pointer to slave transmit buffer. */ - uint32_t slave_tx_size; /*!< Size of slave transmit buffer. */ - uint32_t slave_tx_idx; /*!< Current index into slave transmit buffer. */ - - /* Internal receive state: */ - uint8_t * slave_rx_buffer; /*!< Pointer to buffer where data received by a slave will be stored. */ - uint32_t slave_rx_size; /*!< Slave receive buffer size. */ - uint32_t slave_rx_idx; /*!< Current index into slave receive buffer. */ - - /* Configuration for each target slave. */ - mss_spi_slave_cfg_t slaves_cfg[MSS_SPI_MAX_NB_OF_SLAVES]; - - /** Slave received frame handler: */ - mss_spi_frame_rx_handler_t frame_rx_handler; /*!< Pointer to function that will be called when a frame is received when the SPI block is configured as slave. */ - - uint32_t slave_tx_frame; /*!< Value of the data frame that will be transmited when the SPI block is configured as slave. */ - - /* Slave block rx handler: */ - mss_spi_block_rx_handler_t block_rx_handler; /*!< Pointer to the function that will be called when a data block has been received. */ - -} mss_spi_instance_t; - -/***************************************************************************//** - This instance of mss_spi_instance_t holds all data related to the operations - performed by MSS SPI 0. A pointer to g_mss_spi0 is passed as the first - parameter to MSS SPI driver functions to indicate that MSS SPI 0 should - perform the requested operation. - */ -extern mss_spi_instance_t g_mss_spi0; - -/***************************************************************************//** - This instance of mss_spi_instance_t holds all data related to the operations - performed by MSS SPI 1. A pointer to g_mss_spi1 is passed as the first - parameter to MSS SPI driver functions to indicate that MSS SPI 1 should - perform the requested operation. - */ -extern mss_spi_instance_t g_mss_spi1; - -/***************************************************************************//** - The MSS_SPI_init() function initializes and hardware and data structures of - one of the SmartFusion MSS SPIs. The MSS_SPI_init() function must be called - before any other MSS SPI driver functions can be called. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - Example: - @code - MSS_SPI_init( &g_mss_spi0 ); - @endcode - */ -void MSS_SPI_init -( - mss_spi_instance_t * this_spi -); - -/***************************************************************************//** - The MSS_SPI_configure_slave_mode() function configure a MSS SPI block for - operations as a slave SPI device. It configures the SPI hardware with the - selected SPI protocol mode and clock speed. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - @param protocol_mode - Serial peripheral interface operating mode. Allowed values are: - - MSS_SPI_MODE0 - - MSS_SPI_MODE1 - - MSS_SPI_MODE2 - - MSS_SPI_MODE3 - - MSS_TI_MODE - - MSS_NSC_MODE - - @param clk_rate - Divider value used to generate serial interface clock signal from PCLK. - Allowed values are: - - MSS_SPI_PCLK_DIV_2 - - MSS_SPI_PCLK_DIV_4 - - MSS_SPI_PCLK_DIV_8 - - MSS_SPI_PCLK_DIV_16 - - MSS_SPI_PCLK_DIV_32 - - MSS_SPI_PCLK_DIV_64 - - MSS_SPI_PCLK_DIV_128 - - MSS_SPI_PCLK_DIV_256 - - @param frame_bit_length - Number of bits making up the frame. The maximum frame length is 32 bits. You - must use the MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE constant as the value for - frame_bit_length when configuring the MSS SPI master for block transfer - transactions with the target SPI slave. - - Example: - @code - MSS_SPI_init( &g_mss_spi0 ); - MSS_SPI_configure_slave_mode - ( - &g_mss_spi0, - MSS_SPI_MODE2, - MSS_SPI_PCLK_DIV_64, - MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE - ); - @endcode - - */ -void MSS_SPI_configure_slave_mode -( - mss_spi_instance_t * this_spi, - mss_spi_protocol_mode_t protocol_mode, - mss_spi_pclk_div_t clk_rate, - uint8_t frame_bit_length -); - -/***************************************************************************//** - The MSS_SPI_configure_master_mode() function configures the protocol mode, - serial clock speed and frame size for a specific target SPI slave device. It - is used when the MSS SPI hardware block is used as a SPI master. This function - must be called once for each target SPI slave the SPI master is going to - communicate with. The SPI master hardware will be configured with the - configuration specified by this function during calls to - MSS_SPI_set_slave_select(). - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - - @param slave - The slave parameter is used to identify a target SPI slave. The driver will - hold the MSS SPI master configuration required to communicate with this - slave, as specified by the other function parameters. Allowed values are: - • MSS_SPI_SLAVE_0 - • MSS_SPI_SLAVE_1 - • MSS_SPI_SLAVE_2 - • MSS_SPI_SLAVE_3 - • MSS_SPI_SLAVE_4 - • MSS_SPI_SLAVE_5 - • MSS_SPI_SLAVE_6 - • MSS_SPI_SLAVE_7 - - @param protocol_mode - Serial peripheral interface operating mode. Allowed values are: - • MSS_SPI_MODE0 - • MSS_SPI_MODE1 - • MSS_SPI_MODE2 - • MSS_SPI_MODE3 - • MSS_SPI_TI_MODE - • MSS_SPI_NSC_MODE - - @param clk_rate - Divider value used to generate serial interface clock signal from PCLK. - Allowed values are: - • MSS_SPI_PCLK_DIV_2 - • MSS_SPI_PCLK_DIV_4 - • MSS_SPI_PCLK_DIV_8 - • MSS_SPI_PCLK_DIV_16 - • MSS_SPI_PCLK_DIV_32 - • MSS_SPI_PCLK_DIV_64 - • MSS_SPI_PCLK_DIV_128 - • MSS_SPI_PCLK_DIV_256 - - @param frame_bit_length - Number of bits making up the frame. The maximum frame length is 32 bits. You - must use the MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE constant as the value for - frame_bit_length when configuring the MSS SPI master for block transfer - transactions with the target SPI slave. - - Example: - @code - MSS_SPI_init( &g_mss_spi0 ); - - MSS_SPI_configure_master_mode - ( - &g_mss_spi0, - MSS_SPI_SLAVE_0, - MSS_SPI_MODE2, - MSS_SPI_PCLK_DIV_64, - 12 - ); - - MSS_SPI_configure_master_mode - ( - &g_mss_spi0, - MSS_SPI_SLAVE_1, - MSS_SPI_TI_MODE, - MSS_SPI_PCLK_DIV_128, - MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE - ); - @endcode - */ -void MSS_SPI_configure_master_mode -( - mss_spi_instance_t * this_spi, - mss_spi_slave_t slave, - mss_spi_protocol_mode_t protocol_mode, - mss_spi_pclk_div_t clk_rate, - uint8_t frame_bit_length -); - -/*============================================================================== - * Master functions - *============================================================================*/ - -/***************************************************************************//** - The MSS_SPI_slave_select() function is used by a MSS SPI master to select a - specific slave. This function causes the relevant slave select signal to be - asserted. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - - @param slave - The slave parameter is one of mss_spi_slave_t enumerated constants - identifying a slave. - - Example: - @code - const uint8_t frame_size = 25; - const uint32_t master_tx_frame = 0x0100A0E1; - - MSS_SPI_init( &g_mss_spi0 ); - MSS_SPI_configure_master_mode - ( - &g_mss_spi0, - MSS_SPI_SLAVE_0, - MSS_SPI_MODE1, - MSS_SPI_PCLK_DIV_256, - frame_size - ); - - MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - MSS_SPI_transfer_frame( &g_mss_spi0, master_tx_frame ); - MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - @endcode - */ -void MSS_SPI_set_slave_select -( - mss_spi_instance_t * this_spi, - mss_spi_slave_t slave -); - -/***************************************************************************//** - The MSS_SPI_clear_slave_select() function is used by a MSS SPI Master to - deselect a specific slave. This function causes the relevant slave select - signal to be de-asserted. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - - @param slave - The slave parameter is one of mss_spi_slave_t enumerated constants - identifying a slave. - - Example: - @code - const uint8_t frame_size = 25; - const uint32_t master_tx_frame = 0x0100A0E1; - - MSS_SPI_init( &g_mss_spi0 ); - MSS_SPI_configure_master_mode - ( - &g_mss_spi0, - MSS_SPI_SLAVE_0, - MSS_SPI_MODE1, - MSS_SPI_PCLK_DIV_256, - frame_size - ); - MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - MSS_SPI_transfer_frame( &g_mss_spi0, master_tx_frame ); - MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - @endcode - */ -void MSS_SPI_clear_slave_select -( - mss_spi_instance_t * this_spi, - mss_spi_slave_t slave -); - -/***************************************************************************//** - The MSS_SPI_disable() function is used to temporarily disable a MSS SPI - hardware block. This function is typically used in conjunction with the - SPI_set_transfer_byte_count() function to setup a DMA controlled SPI transmit - transaction as the SPI_set_transfer_byte_count() function must only be used - when the MSS SPI hardware is disabled. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - Example: - @code - uint32_t transfer_size; - uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - - transfer_size = sizeof(tx_buffer); - - MSS_SPI_disable( &g_mss_spi0 ); - MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size ); - PDMA_start - ( - PDMA_CHANNEL_0, - (uint32_t)tx_buffer, - PDMA_SPI1_TX_REGISTER, - transfer_size - ); - MSS_SPI_enable( &g_mss_spi0 ); - - while ( !MSS_SPI_tx_done( &g_mss_spi0 ) ) - { - ; - } - @endcode - */ -static __INLINE void MSS_SPI_disable -( - mss_spi_instance_t * this_spi -) -{ - this_spi->hw_reg_bit->CTRL_ENABLE = 0; -} - -/***************************************************************************//** - The MSS_SPI_enable() function is used to re-enable a MSS SPI hardware block - after it was disabled using the SPI_disable() function. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - Example: - @code - uint32_t transfer_size; - uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - - transfer_size = sizeof(tx_buffer); - - MSS_SPI_disable( &g_mss_spi0 ); - MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size ); - PDMA_start - ( - PDMA_CHANNEL_0, - (uint32_t)tx_buffer, - PDMA_SPI1_TX_REGISTER, - transfer_size - ); - MSS_SPI_enable( &g_mss_spi0 ); - - while ( !MSS_SPI_tx_done( &g_mss_spi0 ) ) - { - ; - } - @endcode - */ -static __INLINE void MSS_SPI_enable -( - mss_spi_instance_t * this_spi -) -{ - this_spi->hw_reg_bit->CTRL_ENABLE = 1; -} - -/***************************************************************************//** - The MSS_SPI_set_transfer_byte_count() function is used as part of setting up - a SPI transfer using DMA. It specifies the number of bytes that must be - transferred before MSS_SPI_tx_done() indicates that the transfer is complete. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - - @param byte_count - The byte_count parameter specifies the number of bytes that must be - transferred by the SPI hardware block considering that a transaction has - been completed. - - Example: - @code - uint32_t transfer_size; - uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - - transfer_size = sizeof(tx_buffer); - - MSS_SPI_disable( &g_mss_spi0 ); - - MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size ); - - PDMA_start( PDMA_CHANNEL_0, (uint32_t)tx_buffer, 0x40011014, transfer_size ); - - MSS_SPI_enable( &g_mss_spi0 ); - - while ( !MSS_SPI_tx_done( &g_mss_spi0) ) - { - ; - } - @endcode - */ -static __INLINE void MSS_SPI_set_transfer_byte_count -( - mss_spi_instance_t * this_spi, - uint16_t byte_count -) -{ - const uint32_t TXRXDFCOUNT_SHIFT = 8U; - const uint32_t TXRXDFCOUNT_MASK = 0x00FFFF00U; - - this_spi->hw_reg->CONTROL = (this_spi->hw_reg->CONTROL & ~TXRXDFCOUNT_MASK) | ( (byte_count << TXRXDFCOUNT_SHIFT) & TXRXDFCOUNT_MASK); - this_spi->hw_reg->TXRXDF_SIZE = 8U; -} - -/***************************************************************************//** - The MSS_SPI_tx_done() function is used to find out if a DMA controlled transfer - has completed. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - Example: - @code - uint32_t transfer_size; - uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - - transfer_size = sizeof(tx_buffer); - - MSS_SPI_disable( &g_mss_spi0 ); - - MSS_SPI_set_transfer_byte_count( &g_mss_spi0, transfer_size ); - - PDMA_start - ( - PDMA_CHANNEL_0, - (uint32_t)tx_buffer, - PDMA_SPI1_TX_REGISTER, - transfer_size - ); - - MSS_SPI_enable( &g_mss_spi0 ); - - while ( !MSS_SPI_tx_done(&g_mss_spi0) ) - { - ; - } - @endcode - */ -static __INLINE uint32_t MSS_SPI_tx_done -( - mss_spi_instance_t * this_spi -) -{ - return this_spi->hw_reg_bit->STATUS_TX_DONE; -} - -/***************************************************************************//** - The MSS_SPI_transfer_frame() function is used by a MSS SPI master to transmit - and receive a frame up to 32 bits long. This function is typically used for - transactions with a SPI slave where the number of transmit and receive bits is - not divisible by 8. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - - @param tx_bits - The tx_bits parameter is a 32 bits word containing the value that will be - transmitted. - Note: The bit length of the value to be transmitted to the slave must be - specified as the frame_bit_length parameter in a previous call to - the MSS_SPI_configure_master() function. - - @return - This function returns a 32 bits word containing the value that is received - from the slave. - - Example: - @code - const uint8_t frame_size = 25; - const uint32_t master_tx_frame = 0x0100A0E1; - uint32_t master_rx; - - MSS_SPI_init( &g_mss_spi0 ); - MSS_SPI_configure_master_mode - ( - &g_mss_spi0, - MSS_SPI_SLAVE_0, - MSS_SPI_MODE1, - MSS_SPI_PCLK_DIV_256, - frame_size - ); - - MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - master_rx = MSS_SPI_transfer_frame( &g_mss_spi0, master_tx_frame ); - MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - @endcode - */ -uint32_t MSS_SPI_transfer_frame -( - mss_spi_instance_t * this_spi, - uint32_t tx_bits -); - -/***************************************************************************//** - The MSS_SPI_transfer_block() function is used by MSS SPI masters to transmit - and receive blocks of data organized as a specified number of bytes. It can be - used for: - • Writing a data block to a slave - • Reading a data block from a slave - • Sending a command to a slave followed by reading the outcome of the - command in a single SPI transaction. This function can be used alongside - Peripheral DMA functions to perform the actual moving to and from the SPI - hardware block using Peripheral DMA. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - - @param cmd_buffer - The cmd_buffer parameter is a pointer to the buffer containing the data that - will be sent by the master from the beginning of the transfer. This pointer - can be null (0) if the master does not need to send a command before reading - data or if the command part of the transfer is written to the SPI hardware - block using DMA. - - @param cmd_byte_size - The cmd_byte_size parameter specifies the number of bytes contained in - cmd_buffer that will be sent. A value of 0 indicates that no data needs to - be sent to the slave. A non-zero value while the cmd_buffer pointer is 0 is - used to indicate that the command data will be written to the SPI hardware - block using DMA. - - @param rd_buffer - The rd_buffer parameter is a pointer to the buffer where the data received - from the slave after the command has been sent will be stored. - - @param rd_byte_size - The rd_byte_size parameter specifies the number of bytes to be received from - the slave and stored in the rd_buffer. A value of 0 indicates that no data - is to be read from the slave. A non-zero value while the rd_buffer pointer - is null (0) is used to specify the receive size when using DMA to read from - the slave. - Note: All bytes received from the slave, including the bytes received - while the command is sent, will be read through DMA. - - Polled write transfer example: - @code - uint8_t master_tx_buffer[MASTER_TX_BUFFER] = - { - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A - }; - MSS_SPI_init( &g_mss_spi0 ); - MSS_SPI_configure_master_mode - ( - &g_mss_spi0, - MSS_SPI_SLAVE_0, - MSS_SPI_MODE1, - MSS_SPI_PCLK_DIV_256, - MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE - ); - - MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - MSS_SPI_transfer_block - ( - &g_mss_spi0, - master_tx_buffer, - sizeof(master_tx_buffer), - 0, - 0 - ); - MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - @endcode - - DMA transfer example: - In this example the transmit and receive buffers are not specified as part of - the call to MSS_SPI_transfer_block(). MSS_SPI_transfer_block() will only - prepare the MSS SPI hardware for a transfer. The MSS SPI transmit hardware - FIFO is filled using one DMA channel and a second DMA channel is used to read - the content of the MSS SPI receive hardware FIFO. The transmit and receive - buffers are specified by two separate calls to PDMA_start() to initiate DMA - transfers on the channel used for transmit data and the channel used for - receive data. - @code - uint8_t master_tx_buffer[MASTER_RX_BUFFER] = - { - 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA - }; - uint8_t slave_rx_buffer[MASTER_RX_BUFFER] = - { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A - }; - MSS_SPI_init( &g_mss_spi0 ); - - MSS_SPI_configure_master_mode - ( - &g_mss_spi0, - MSS_SPI_SLAVE_0, - MSS_SPI_MODE1, - MSS_SPI_PCLK_DIV_256, - MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE - ); - MSS_SPI_set_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - MSS_SPI_transfer_block( &g_mss_spi0, 0, 0, 0, 0 ); - PDMA_start - ( - PDMA_CHANNEL_1, - PDMA_SPI0_RX_REGISTER, - (uint32_t)master_rx_buffer, - sizeof(master_rx_buffer) - ); - PDMA_start - ( - PDMA_CHANNEL_2, - (uint32_t)master_tx_buffer, - PDMA_SPI0_TX_REGISTER, - sizeof(master_tx_buffer) - ); - while( PDMA_status(PDMA_CHANNEL_1) == 0 ) - { - ; - } - MSS_SPI_clear_slave_select( &g_mss_spi0, MSS_SPI_SLAVE_0 ); - @endcode - */ -void MSS_SPI_transfer_block -( - mss_spi_instance_t * this_spi, - const uint8_t * cmd_buffer, - uint16_t cmd_byte_size, - uint8_t * rd_buffer, - uint16_t rd_byte_size -); - -/*============================================================================== - * Slave functions - *============================================================================*/ - -/***************************************************************************//** - The MSS_SPI_set_frame_rx_handler() function is used by MSS SPI slaves to - specify the receive handler function that will be called by the MSS SPI driver - interrupt handler when a a frame of data is received by the MSS SPI slave. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - - @param rx_handler - The rx_handler parameter is a pointer to the frame receive handler that must - be called when a frame is received by the MSS SPI slave. - - Example: - @code - uint32_t g_slave_rx_frame = 0; - - void slave_frame_handler( uint32_t rx_frame ) - { - g_slave_rx_frame = rx_frame; - } - - int setup_slave( void ) - { - const uint16_t frame_size = 25; - MSS_SPI_init( &g_mss_spi1 ); - MSS_SPI_configure_slave_mode - ( - &g_mss_spi0, - MSS_SPI_MODE2, - MSS_SPI_PCLK_DIV_64, - frame_size - ); - MSS_SPI_set_frame_rx_handler( &g_mss_spi1, slave_frame_handler ); - } - @endcode - */ -void MSS_SPI_set_frame_rx_handler -( - mss_spi_instance_t * this_spi, - mss_spi_frame_rx_handler_t rx_handler -); - -/***************************************************************************//** - The MSS_SPI_set_slave_tx_frame() function is used by MSS SPI slaves to specify - the frame that will be transmitted when a transaction is initiated by the SPI - master. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - - @param frame_value - The frame_value parameter contains the value of the frame to be sent to the - master. - Note: The bit length of the value to be transmitted to the master must be - specified as the frame_bit_length parameter in a previous call to - the MSS_SPI_configure_slave() function. - - Example: - @code - const uint16_t frame_size = 25; - const uint32_t slave_tx_frame = 0x0110F761; - uint32_t master_rx; - - MSS_SPI_init( &g_mss_spi1 ); - MSS_SPI_configure_slave_mode - ( - &g_mss_spi0, - MSS_SPI_MODE2, - MSS_SPI_PCLK_DIV_64, - frame_size - ); - MSS_SPI_set_slave_tx_frame( &g_mss_spi1, slave_tx_frame ); - @endcode - */ -void MSS_SPI_set_slave_tx_frame -( - mss_spi_instance_t * this_spi, - uint32_t frame_value -); - -/***************************************************************************//** - The MSS_SPI_set_slave_block_buffers() function is used to configure an MSS - SPI slave for block transfer operations. It specifies one or more of the - following: - • The data that will be transmitted when accessed by a master. - • The buffer where data received from a master will be stored. - • The handler function that must be called after the receive buffer has been - filled. - • The number of bytes that must be received from the master before the receive - handler function is called. - These parameters allow the following use cases: - • Slave performing an action after receiving a block of data from a master - containing a command. The action will be performed by the receive handling - based on the content of the receive data buffer. - • Slave returning a block of data to the master. The type of information is - always the same but the actual values change over time. For example, - returning the voltage of a predefined set of analog inputs. - • Slave returning data based on a command contained in the first part of the - SPI transaction. For example, reading the voltage of the analog input - specified by the first data byte by the master. This is achieved by setting - the rx_buff_size parameter to the number of received bytes making up the - command. - - @param this_spi - The this_spi parameter is a pointer to an mss_spi_instance_t structure - identifying the MSS SPI hardware block to be initialized. There are two such - data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and - MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 - or g_mss_spi1 global data structure defined within the SPI driver. - - - @param tx_buffer - The tx_buffer parameter is a pointer to a buffer containing the data that - will be sent to the master. This parameter can be set to 0 if the MSS SPI - slave is not intended to be the target of SPI read transactions or if DMA - is used to transfer SPI read data into the MSS SPI slave. - - @param tx_buff_size - The tx_buff_size parameter specifies the number of bytes contained in the - tx_buffer. This parameter can be set to 0 if the MSS SPI slave is not - intended to be the target of SPI read transactions or if DMA is used to - transfer SPI read data into the MSS SPI slave. - - @param rx_buffer - The rx_buffer parameter is a pointer to the buffer where data received from - the master will be stored. This parameter can be set to 0 if the MSS SPI - slave is not intended to be the target of SPI write or write-read - transactions. It can also set to 0 if the MSS SPI slave uses DMA to handle - data written to it. - - @param rx_buff_size - The rx_buff_size parameter specifies the size of the receive buffer. It is - also the number of bytes that must be received before the receive handler - is called, if a receive handler is specified using the block_rx_handler - parameter. This parameter can be set to 0 if the MSS SPI slave is not - intended to be the target of SPI write or write-read transactions. It can - also set to 0 if the MSS SPI slave uses DMA to handle data written to it. - - @param block_rx_handler - The block_rx_handler parameter is a pointer to a function that will be - called when the receive buffer has been filled. This parameter can be set - to 0 if the MSS SPI slave is not intended to be the target of SPI write or - write-read transactions. It can also set to 0 if the MSS SPI slave uses DMA - to handle data written to it. - - Slave performing operation based on master command: - In this example the SPI slave is configured to receive 10 bytes of data or - command from the SPI slave and process the data received from the master. - @code - uint32_t nb_of_rx_handler_calls = 0; - - void spi1_block_rx_handler_b - ( - uint8_t * rx_buff, - uint16_t rx_size - ) - { - ++nb_of_rx_handler_calls; - } - - void setup_slave( void ) - { - uint8_t slave_rx_buffer[10] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - MSS_SPI_init( &g_mss_spi1 ); - MSS_SPI_configure_slave_mode - ( - &g_mss_spi0, - MSS_SPI_MODE2, - MSS_SPI_PCLK_DIV_64, - MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE - ); - - MSS_SPI_set_slave_block_buffers - ( - &g_mss_spi1, - 0, - 0, - slave_rx_buffer, - sizeof(master_tx_buffer), - spi1_block_rx_handler_b - ); - } - @endcode - - Slave responding to command example: - In this example the slave will return data based on a command sent by the - master. The first part of the transaction is handled using polled mode where - each byte returned to the master is written as part of the interrupt service - routine. The second part of the transaction, where the slave returns data - based on the command value, is sent using a DMA transfer initiated by the - receive handler. - @code - static uint8_t g_spi1_tx_buffer_b[SLAVE_TX_BUFFER_SIZE] = - { - 5, 6, 7, 8, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 - }; - - void spi1_block_rx_handler - ( - uint8_t * rx_buff, - uint16_t rx_size - ) - { - if ( rx_buff[2] == 0x99 ) - { - PDMA_start - ( - PDMA_CHANNEL_0, - (uint32_t)g_spi1_tx_buffer_b, - 0x40011014, - sizeof(g_spi1_tx_buffer_b) - ); - } - } - - void setup_slave( void ) - { - uint8_t slave_preamble[8] = { 9, 10, 11, 12, 13, 14, 16, 16 }; - - MSS_SPI_init( &g_mss_spi1 ); - MSS_SPI_configure_slave_mode - ( - &g_mss_spi0, - MSS_SPI_MODE2, - MSS_SPI_PCLK_DIV_64, - MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE - ); - - PDMA_init(); - PDMA_configure - ( - PDMA_CHANNEL_0, - TO_SPI_1, - LOW_PRIORITY | BYTE_TRANSFER | INC_SRC_ONE_BYTE - ); - - MSS_SPI_set_slave_block_buffers - ( - &g_mss_spi1, - slave_preamble, - 4, - g_spi1_rx_buffer, - sizeof(g_spi1_rx_buffer), - spi1_block_rx_handler - ); - } - @endcode - */ -void MSS_SPI_set_slave_block_buffers -( - mss_spi_instance_t * this_spi, - const uint8_t * tx_buffer, - uint32_t tx_buff_size, - uint8_t * rx_buffer, - uint32_t rx_buff_size, - mss_spi_block_rx_handler_t block_rx_handler -); - -#ifdef __cplusplus -} -#endif - -#endif /* MSS_SPI_H_*/ diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.c b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.c deleted file mode 100644 index 7dbb6c010..000000000 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.c +++ /dev/null @@ -1,458 +0,0 @@ -/******************************************************************************* - * (c) Copyright 2007 Actel Corporation. All rights reserved. - * - * SmartFusion Microcontroller Subsystem UART bare metal software driver - * implementation. - * - * SVN $Revision: 1898 $ - * SVN $Date: 2009-12-21 17:27:57 +0000 (Mon, 21 Dec 2009) $ - */ -#include "mss_uart.h" -#include "../../CMSIS/mss_assert.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/******************************************************************************* - * defines - */ -#define TX_READY 0x01U -#define TX_COMPLETE 0U - -#define TX_FIFO_SIZE 16U - -#define FCR_TRIG_LEVEL_MASK 0xC0U - -#define IIRF_MASK 0x0FU - -/******************************************************************************* - * Possible values for Interrupt Identification Register Field. - */ -#define IIRF_MODEM_STATUS 0x00U -#define IIRF_THRE 0x02U -#define IIRF_RX_DATA 0x04U -#define IIRF_RX_LINE_STATUS 0x06U -#define IIRF_DATA_TIMEOUT 0x0CU - -/******************************************************************************* - * Cortex-M3 interrupt handler functions implemented as part of the MSS UART - * driver. - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void UART0_IRQHandler( void ); -#else -void UART0_IRQHandler( void ); -#endif - -#if defined(__GNUC__) -__attribute__((__interrupt__)) void UART1_IRQHandler( void ); -#else -void UART1_IRQHandler( void ); -#endif - -/******************************************************************************* - * Local functions. - */ -static void MSS_UART_isr( mss_uart_instance_t * this_uart ); - -/******************************************************************************* - * - */ -mss_uart_instance_t g_mss_uart0; -mss_uart_instance_t g_mss_uart1; - -/***************************************************************************//** - * UART_init. - * Initialises the UART with default configuration. - */ -void -MSS_UART_init -( - mss_uart_instance_t* this_uart, - uint32_t baud_rate, - uint8_t line_config -) -{ - uint16_t baud_value; - uint32_t pclk_freq; - - /* The driver expects g_mss_uart0 and g_mss_uart1 to be the only - * mss_uart_instance_t instances used to identfy UART0 and UART1. */ - ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); - - /* Force the value of the CMSIS global variables holding the various system - * clock frequencies to be updated. */ - SystemCoreClockUpdate(); - - if ( this_uart == &g_mss_uart0 ) - { - this_uart->hw_reg = UART0; - this_uart->hw_reg_bit = UART0_BITBAND; - this_uart->irqn = UART0_IRQn; - - pclk_freq = g_FrequencyPCLK0; - - /* reset UART0 */ - SYSREG->SOFT_RST_CR |= SYSREG_UART0_SOFTRESET_MASK; - /* Clear any previously pended UART0 interrupt */ - NVIC_ClearPendingIRQ( UART0_IRQn ); - /* Take UART0 out of reset. */ - SYSREG->SOFT_RST_CR &= ~SYSREG_UART0_SOFTRESET_MASK; - } - else - { - this_uart->hw_reg = UART1; - this_uart->hw_reg_bit = UART1_BITBAND; - this_uart->irqn = UART1_IRQn; - - pclk_freq = g_FrequencyPCLK1; - - /* Reset UART1 */ - SYSREG->SOFT_RST_CR |= SYSREG_UART1_SOFTRESET_MASK; - /* Clear any previously pended UART1 interrupt */ - NVIC_ClearPendingIRQ( UART1_IRQn ); - /* Take UART1 out of reset. */ - SYSREG->SOFT_RST_CR &= ~SYSREG_UART1_SOFTRESET_MASK; - } - - /* disable interrupts */ - this_uart->hw_reg->IER = 0U; - - /* - * Compute baud value based on requested baud rate and PCLK frequency. - * The baud value is computed using the following equation: - * baud_value = PCLK_Frequency / (baud_rate * 16) - * The baud value is rounded up or down depending on what would be the remainder - * of the divide by 16 operation. - */ - baud_value = (uint16_t)(pclk_freq / baud_rate); - if ( baud_value & 0x00000008U ) - { - /* remainder above 0.5 */ - baud_value = (baud_value >> 4U) + 1U; - } - else - { - /* remainder below 0.5 */ - baud_value = (baud_value >> 4U); - } - - /* set divisor latch */ - this_uart->hw_reg_bit->LCR_DLAB = (uint32_t)1; - - /* msb of baud value */ - this_uart->hw_reg->DMR = (uint8_t)(baud_value >> 8); - /* lsb of baud value */ - this_uart->hw_reg->DLR = (uint8_t)baud_value; - - /* reset divisor latch */ - this_uart->hw_reg_bit->LCR_DLAB = (uint32_t)0; - - /* set the line control register (bit length, stop bits, parity) */ - this_uart->hw_reg->LCR = line_config; - - /* FIFO configuration */ - this_uart->hw_reg->FCR = (uint8_t)MSS_UART_FIFO_SINGLE_BYTE; - - /* disable loopback */ - this_uart->hw_reg_bit->MCR_LOOP = (uint32_t)0; - - /* Instance setup */ - this_uart->tx_buff_size = TX_COMPLETE; - this_uart->tx_buffer = (const uint8_t *)0; - this_uart->tx_idx = 0U; - - this_uart->rx_handler = (mss_uart_rx_handler_t)0; -} - -/***************************************************************************//** - * See mss_uart.h for details of how to use this function. - */ -void -MSS_UART_polled_tx -( - mss_uart_instance_t * this_uart, - const uint8_t * pbuff, - uint32_t tx_size -) -{ - uint32_t char_idx; - uint32_t status; - - ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); - - for ( char_idx = 0U; char_idx < tx_size; char_idx++ ) - { - /* Wait for UART to become ready to transmit. */ - do { - status = this_uart->hw_reg_bit->LSR_THRE; - } while ( (status & TX_READY) == 0U ); - /* Send next character in the buffer. */ - this_uart->hw_reg->THR = pbuff[char_idx]; - } -} - -/***************************************************************************//** - * See mss_uart.h for details of how to use this function. - */ -void -MSS_UART_polled_tx_string -( - mss_uart_instance_t * this_uart, - const uint8_t * p_sz_string -) -{ - uint32_t char_idx; - uint32_t status; - - ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); - - char_idx = 0U; - - while ( p_sz_string[char_idx] != 0U ) - { - /* Wait for UART to become ready to transmit. */ - do { - status = this_uart->hw_reg_bit->LSR_THRE; - } while ( (status & TX_READY) == 0U); - /* Send next character in the buffer. */ - this_uart->hw_reg->THR = p_sz_string[char_idx]; - ++char_idx; - } -} - -/***************************************************************************//** - * See mss_uart.h for details of how to use this function. - */ -void -MSS_UART_irq_tx -( - mss_uart_instance_t * this_uart, - const uint8_t * pbuff, - uint32_t tx_size -) -{ - ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); - - if ( tx_size > 0U ) - { - /*Initialise the transmit info for the UART instance with the arguments.*/ - this_uart->tx_buffer = pbuff; - this_uart->tx_buff_size = tx_size; - this_uart->tx_idx = (uint16_t)0; - - /* enables TX interrupt */ - this_uart->hw_reg_bit->IER_ETBEI = (uint32_t)1; - - /* Enable UART instance interrupt in Cortex-M3 NVIC. */ - NVIC_EnableIRQ( this_uart->irqn ); - } -} - -/***************************************************************************//** - * See mss_uart.h for details of how to use this function. - */ -int8_t -MSS_UART_tx_complete -( - mss_uart_instance_t * this_uart -) -{ - int8_t ret_value = 0; - uint32_t transmit_empty = this_uart->hw_reg_bit->LSR_TEMT; - - ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); - - if ( ( TX_COMPLETE == this_uart->tx_buff_size ) && transmit_empty ) - { - ret_value = 1; - } - - return ret_value; -} - - -/***************************************************************************//** - * See mss_uart.h for details of how to use this function. - */ -size_t -MSS_UART_get_rx -( - mss_uart_instance_t * this_uart, - uint8_t * rx_buff, - size_t buff_size -) -{ - size_t rx_size = 0U; - - ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); - - while (( this_uart->hw_reg_bit->LSR_DR != 0U) && ( rx_size < buff_size ) ) - { - rx_buff[rx_size] = this_uart->hw_reg->RBR; - ++rx_size; - } - - return rx_size; -} - -/***************************************************************************//** - * Interrupt service routine triggered by the Transmitter Holding Register - * Empty (THRE) interrupt or Received Data Available (RDA). - * On THRE irq this routine will transmit the data from the transmit buffer. - * When all bytes are transmitted, this routine disables the THRE interrupt - * and resets the transmit counter. - * On RDA irq this routine will call the user's receive handler routine previously - * registered with the UART driver through a call to UART_set_rx_handler(). - */ -static void -MSS_UART_isr -( - mss_uart_instance_t * this_uart -) -{ - uint8_t iirf; - uint32_t tx_empty; - - ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); - - iirf = this_uart->hw_reg->IIR & IIRF_MASK; - - switch ( iirf ) - { - case IIRF_MODEM_STATUS: - break; - - case IIRF_THRE: /* Transmitter Holding Register Empty */ - tx_empty = this_uart->hw_reg_bit->LSR_TEMT; - - if ( tx_empty ) - { - uint32_t i; - uint32_t fill_size = TX_FIFO_SIZE; - uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx; - if ( tx_remain < TX_FIFO_SIZE ) - { - fill_size = tx_remain; - } - /* Fill up FIFO */ - for ( i = 0U; i < fill_size; ++i ) - { - this_uart->hw_reg->THR = this_uart->tx_buffer[this_uart->tx_idx]; - ++this_uart->tx_idx; - } - } - else - { - this_uart->hw_reg->THR = this_uart->tx_buffer[this_uart->tx_idx]; - ++this_uart->tx_idx; - } - - if ( this_uart->tx_idx == this_uart->tx_buff_size ) - { - this_uart->tx_buff_size = TX_COMPLETE; - /* disables TX interrupt */ - this_uart->hw_reg_bit->IER_ETBEI = 0U; - } - break; - - case IIRF_RX_DATA: /* Received Data Available */ - case IIRF_DATA_TIMEOUT: - if (this_uart->rx_handler != 0) - { - (*(this_uart->rx_handler))(); - } - break; - - case IIRF_RX_LINE_STATUS: - break; - - default: - /* Disable other interrupts */ - this_uart->hw_reg_bit->IER_ELSI = 0U; - this_uart->hw_reg_bit->IER_EDSSI = 0U; - break; - } -} - -/***************************************************************************//** - * See mss_uart.h for details of how to use this function. - */ -void -MSS_UART_set_rx_handler -( - mss_uart_instance_t * this_uart, - mss_uart_rx_handler_t handler, - mss_uart_rx_trig_level_t trigger_level -) -{ - ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); - - this_uart->rx_handler = handler; - - /* Set the receive interrupt trigger level. */ - this_uart->hw_reg->FCR = (this_uart->hw_reg->FCR & (uint8_t)(~((uint8_t)FCR_TRIG_LEVEL_MASK))) | (uint8_t)trigger_level; - - /* Enable receive interrupt. */ - this_uart->hw_reg_bit->IER_ERBFI = 1U; - - /* Enable UART instance interrupt in Cortex-M3 NVIC. */ - NVIC_EnableIRQ( this_uart->irqn ); -} - -/***************************************************************************//** - * See mss_uart.h for details of how to use this function. - */ -void -MSS_UART_set_loopback -( - mss_uart_instance_t * this_uart, - mss_uart_loopback_t loopback -) -{ - ASSERT( (this_uart == &g_mss_uart0) || (this_uart == &g_mss_uart1) ); - - if ( loopback == MSS_UART_LOOPBACK_OFF ) - { - this_uart->hw_reg_bit->MCR_LOOP = 0U; - } - else - { - this_uart->hw_reg_bit->MCR_LOOP = 1U; - } -} - -/***************************************************************************//** - * UART0 interrupt service routine. - * UART0_IRQHandler is included within the Cortex-M3 vector table as part of the - * Fusion 2 CMSIS. - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void UART0_IRQHandler( void ) -#else -void UART0_IRQHandler( void ) -#endif -{ - MSS_UART_isr( &g_mss_uart0 ); - NVIC_ClearPendingIRQ( UART0_IRQn ); -} - -/***************************************************************************//** - * UART1 interrupt service routine. - * UART2_IRQHandler is included within the Cortex-M3 vector table as part of the - * Fusion 2 CMSIS. - */ -#if defined(__GNUC__) -__attribute__((__interrupt__)) void UART1_IRQHandler( void ) -#else -void UART1_IRQHandler( void ) -#endif -{ - MSS_UART_isr( &g_mss_uart1 ); - NVIC_ClearPendingIRQ( UART1_IRQn ); -} - -#ifdef __cplusplus -} -#endif diff --git a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.h b/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.h deleted file mode 100644 index 3897a3c37..000000000 --- a/Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mss_uart/mss_uart.h +++ /dev/null @@ -1,626 +0,0 @@ -/******************************************************************************* - * (c) Copyright 2007 Actel Corporation. All rights reserved. - * - * SmartFusion Microcontroller Subsystem UART bare metal software driver public API. - * - * SVN $Revision: 1942 $ - * SVN $Date: 2009-12-22 17:48:07 +0000 (Tue, 22 Dec 2009) $ - */ -/*=========================================================================*//** - @mainpage SmartFusion MSS UART Bare Metal Driver. - - @section intro_sec Introduction - The SmartFusion MicroController Subsystem (MSS) includes two UART peripherals - for serial communications. - This driver provides a set of functions for controlling the MSS UARTs as part - of a bare metal system where no operating system is available. These drivers - can be adapted for use as part of an operating system but the implementation - of the adaptation layer between this driver and the operating system's driver - model is outside the scope of this driver. - - @section hw_dependencies Hardware Flow Dependencies - The configuration of all features of the MSS UARTs is covered by this driver - with the exception of the SmartFusion IOMUX configuration. SmartFusion allows - multiple non-concurrent uses of some external pins through IOMUX configuration. - This feature allows optimization of external pin usage by assigning external - pins for use by either the microcontroller subsystem or the FPGA fabric. The - MSS UARTs serial signals are routed through IOMUXes to the SmartFusion device - external pins. These IOMUXes are configured automatically by the MSS - configurator tool in the hardware flow correctly when the MSS UARTs are enabled - in that tool. You must ensure that the MSS UARTs are enabled by the MSS - configurator tool in the hardware flow; otherwise the serial inputs and outputs - will not be connected to the chip's external pins. For more information on - IOMUX, refer to the IOMUX section of the SmartFusion Datasheet. - The base address, register addresses and interrupt number assignment for the MSS - UART blocks are defined as constants in the SmartFusion CMSIS-PAL You must ensure - that the SmartFusion CMSIS-PAL is either included in the software tool chain used - to build your project or is included in your project. - - - @section theory_op Theory of Operation - The MSS UART driver uses the SmartFusion "Cortex Microcontroler Software - Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access hadware - registers. You must ensure that the SmartFusion CMSIS-PAL is either included - in the software toolchain used to build your project or is included in your - project. The most up to date SmartFusion CMSIS-PAL files can be obtained using - the Actel Firmware Catalog. - - The MSS UART driver functions are logically grouped into three groups: - - Initialization functions - - Polled transmit and receive functions - - Interrupt driven transmit and receive functions - - The MSS UART driver is initialized through a call to the UART_init() function. - This function takes the UART's configuration as parameters. The UART_init() - function must be called before any other UART driver functions can be called. - The first parameter of the UART_init() function is a pointer to one of two - global data structures used to store state information for each UART driver. - A pointer to these data structures is also used as first parameter to any of - the driver functions to identify which UART will be used by the called - function. The name of these two data structures are g_mss_uart0 and - g_mss_uart1. Therefore any call to a MSS UART function should be of the form - UART_function_name( &g_mss_uart0, ... ) or UART_function_name( &g_mss_uart1, ... ). - The two SmartFusion MSS UARTs can also be configured to loop back to each - other using the MSS_set_loopback() function for debugging purposes. - - Polled operations where the processor constantly poll the UART registers state - in order to control data transmit or data receive is performed using functions: - - MSS_UART_polled_tx() - - MSS_UART_get_rx() - - Interrupt driven operations where the processor sets up transmit or receive - then returns to performing some other operation until an interrupts occurs - indicating that its attention is required is performed using functions: - - MSS_UART_irq_tx() - - MSS_UART_tx_complete() - - MSS_UART_set_rx_handler() - - MSS_UART_get_rx() - Interrupt driven transmit is initiated by a call to MSS_UART_irq_tx() specifying - the block of data to transmit. The processor can then perform some other - operation and later inquire whether transmit has completed by calling the - MSS_UART_tx_complete() function. - Interrupt driven receive is performed by first registering a receive handler - function that will be called by the driver whenever receive data is available. - This receive handler function in turns calls the MSS_UART_get_rx() function to - actually read the received data. - - *//*=========================================================================*/ -#ifndef __MSS_UART_H_ -#define __MSS_UART_H_ 1 - -#include "../../CMSIS/a2fxxxm3.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************//** - Baud rates. - The following definitions are used to specify standard baud rates as a - parameter to the MSS_UART_init() function. - */ -#define MSS_UART_110_BAUD 110 -#define MSS_UART_300_BAUD 300 -#define MSS_UART_1200_BAUD 1200 -#define MSS_UART_2400_BAUD 2400 -#define MSS_UART_4800_BAUD 4800 -#define MSS_UART_9600_BAUD 9600 -#define MSS_UART_19200_BAUD 19200 -#define MSS_UART_38400_BAUD 38400 -#define MSS_UART_57600_BAUD 57600 -#define MSS_UART_115200_BAUD 115200 -#define MSS_UART_230400_BAUD 230400 -#define MSS_UART_460800_BAUD 460800 -#define MSS_UART_921600_BAUD 921600 - -/***************************************************************************//** - Data bits length values. - - The following defines are used to build the value of the MSS_UART_init() - function line_config parameter. - */ -#define MSS_UART_DATA_5_BITS 0x00 -#define MSS_UART_DATA_6_BITS 0x01 -#define MSS_UART_DATA_7_BITS 0x02 -#define MSS_UART_DATA_8_BITS 0x03 - -/***************************************************************************//** - Parity values - The following defines are used to build the value of the MSS_UART_init() - function line_config parameter. - */ -#define MSS_UART_NO_PARITY 0x00 -#define MSS_UART_ODD_PARITY 0x08 -#define MSS_UART_EVEN_PARITY 0x18 -#define MSS_UART_STICK_PARITY_0 0x38 -#define MSS_UART_STICK_PARITY_1 0x28 - -/***************************************************************************//** - Stop bit values - The following defines are used to build the value of the MSS_UART_init() - function line_config parameter. - */ -#define MSS_UART_ONE_STOP_BIT 0x00 -#define MSS_UART_ONEHALF_STOP_BIT 0x04 -#define MSS_UART_TWO_STOP_BITS 0x04 - -/***************************************************************************//** - FIFO trigger sizes - This enumeration specifies the number of bytes that must be received before a - receive interrupt is generated. This enumeration provides the allowed values for - the MSS_UART_set_rx_handler() function trigger_level parameter. - */ -typedef enum __mss_uart_rx_trig_level_t { - MSS_UART_FIFO_SINGLE_BYTE = 0x00, - MSS_UART_FIFO_FOUR_BYTES = 0x40, - MSS_UART_FIFO_EIGHT_BYTES = 0x80, - MSS_UART_FIFO_FOURTEEN_BYTES = 0xC0 -} mss_uart_rx_trig_level_t; - -/***************************************************************************//** - Loopback. - This enumeration is used as parameter to function MSS_UART_set_loopback(). It - specifies the loopback configuration of the UARTs. Using MSS_UART_LOOPBACK_ON - as parameter to function MSS_UART_set_loopback() will set up the UART to locally - loopback its Tx and Rx lines. - */ -typedef enum __mss_uart_loopback_t { - MSS_UART_LOOPBACK_OFF = 0, - MSS_UART_LOOPBACK_ON = 1 -} mss_uart_loopback_t; - -/***************************************************************************//** - Receive handler prototype. - This typedef specifies the prototype of functions that can be registered with - this driver as receive handler functions. - */ -typedef void (*mss_uart_rx_handler_t)(void); - -/***************************************************************************//** - mss_uart_instance_t. - - There is one instance of this structure for each instance of the Microcontroller - Subsystem's UARTs. Instances of this structure are used to identify a specific - UART. A pointer to an instance of the mss_uart_instance_t structure is passed - as the first parameter to MSS UART driver functions to identify which UART - should perform the requested operation. - */ -typedef struct { - /* CMSIS related defines identifying the UART hardware. */ - UART_TypeDef * hw_reg; /*!< Pointer to UART registers. */ - UART_BitBand_TypeDef * hw_reg_bit; /*!< Pointer to UART registers bit band area. */ - IRQn_Type irqn; /*!< UART's Cortex-M3 NVIC interrupt number. */ - - /* transmit related info (used with interrupt driven trnasmit): */ - const uint8_t * tx_buffer; /*!< Pointer to transmit buffer. */ - uint32_t tx_buff_size; /*!< Transmit buffer size. */ - uint32_t tx_idx; /*!< Index within trnamit buffer of next byte to transmit.*/ - - /* receive interrupt handler:*/ - mss_uart_rx_handler_t rx_handler; /*!< Pointer to user registered received handler. */ -} mss_uart_instance_t; - -/***************************************************************************//** - This instance of mss_uart_instance_t holds all data related to the operations - performed by UART0. A pointer to g_mss_uart0 is passed as the first parameter - to MSS UART driver functions to indicate that UART0 should perform the requested - operation. - */ -extern mss_uart_instance_t g_mss_uart0; - -/***************************************************************************//** - This instance of mss_uart_instance_t holds all data related to the operations - performed by UART1. A pointer to g_mss_uart1 is passed as the first parameter - to MSS UART driver functions to indicate that UART1 should perform the requested - operation. - */ -extern mss_uart_instance_t g_mss_uart1; - -/***************************************************************************//** - The MSS_UART_init() function initializes and configures one of the SmartFusion - MSS UARTs with the configuration passed as a parameter. The configuration - parameters are the baud_rate which is used to generate the baud value and the - line_config which is used to specify the line configuration (bit length, stop - bits and parity). - - Example: - @code - #include "mss_uart.h" - - int main(void) - { - MSS_UART_init - ( - &g_mss_uart0, - MSS_UART_57600_BAUD, - MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT - ); - return(0); - } - @endcode - - @param this_uart - The this_uart parameter is a pointer to an mss_uart_instance_t structure - identifying the MSS UART hardware block to be initialized. There are two - such data structures, g_mss_uart0 and g_mss_uart1, associated with MSS UART0 - and MSS UART1 respectively. This parameter must point to either the - g_mss_uart0 or g_mss_uart1 global data structure defined within the UART - driver. - - - @param baud_rate - The baud_rate parameter specifies the baud rate. It can be specified for - common baud rates' using the following defines: - - MSS_UART_110_BAUD - - MSS_UART_300_BAUD - - MSS_UART_1200_BAUD - - MSS_UART_2400_BAUD - - MSS_UART_4800_BAUD - - MSS_UART_9600_BAUD - - MSS_UART_19200_BAUD - - MSS_UART_38400_BAUD - - MSS_UART_57600_BAUD - - MSS_UART_115200_BAUD - - MSS_UART_230400_BAUD - - MSS_UART_460800_BAUD - - MSS_UART_921600_BAUD - Alternatively, any non standard baud rate can be specified by simply passing - the actual required baud rate as value for this parameter. - - @param line_config - The line_config parameter is the line configuration specifying the bit length, - number of stop bits and parity settings. This is a logical OR of one of the - following to specify the transmit/receive data bit length: - - MSS_UART_DATA_5_BITS - - MSS_UART_DATA_6_BITS, - - MSS_UART_DATA_7_BITS - - MSS_UART_DATA_8_BITS - with one of the following to specify the parity setting: - - MSS_UART_NO_PARITY - - MSS_UART_EVEN_PARITY - - MSS_UART_ODD_PARITY - - MSS_UART_STICK_PARITY_0 - - MSS_UART_STICK_PARITY_1 - with one of the following to specify the number of stop bits: - - MSS_UART_ONE_STOP_BIT - - MSS_UART_ONEHALF_STOP_BIT - - MSS_UART_TWO_STOP_BITS - - @return - This function does not return a value. - */ -void -MSS_UART_init -( - mss_uart_instance_t* this_uart, - uint32_t baud_rate, - uint8_t line_config -); - -/***************************************************************************//** - The function MSS_UART_polled_tx() is used to transmit data. It transfers the - contents of the transmitter data buffer, passed as a function parameter, into - the UART's hardware transmitter FIFO. It returns when the full content of the - transmit data buffer has been transferred to the UART's transmit FIFO. - - @param this_uart - The this_uart parameter is a pointer to an mss_uart_instance_t structure - identifying the MSS UART hardware block that will perform the requested - function. There are two such data structures, g_mss_uart0 and g_mss_uart1, - associated with MSS UART0 and MSS UART1. This parameter must point to either - the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART - driver. - - @param pbuff - The pbuff parameter is a pointer to a buffer containing the data to be - transmitted. - - @param tx_size - The tx_size parameter specifies the size, in bytes, of the data to be - transmitted. - - @return This function does not return a value. - */ -void -MSS_UART_polled_tx -( - mss_uart_instance_t * this_uart, - const uint8_t * pbuff, - uint32_t tx_size -); - -/***************************************************************************//** - The function MSS_UART_polled_tx_string() is used to transmit a zero-terminated - string. It transfers the text found starting at the address pointed to by - p_sz_string into the UART's hardware transmitter FIFO. It returns when the - complete string has been transferred to the UART's transmit FIFO. - - @param this_uart - The this_uart parameter is a pointer to an mss_uart_instance_t structure - identifying the MSS UART hardware block that will perform the requested - function. There are two such data structures, g_mss_uart0 and g_mss_uart1, - associated with MSS UART0 and MSS UART1. This parameter must point to either - the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART - driver. - - @param p_sz_string - The p_sz_string parameter is a pointer to a buffer containing the - zero-terminated string to be transmitted. - - @return This function does not return a value. - */ -void -MSS_UART_polled_tx_string -( - mss_uart_instance_t * this_uart, - const uint8_t * p_sz_string -); - - -/***************************************************************************//** - The function MSS_UART_irq_tx() is used to initiate interrupt driven transmit. It - returns immediately after making a note of the transmit buffer location and - enabling transmit interrupts both at the UART and Cortex-M3 NVIC level. - This function takes a pointer to a memory buffer containing the data to - transmit as parameter. The memory buffer specified through this pointer - should remain allocated and contain the data to transmit until the transmit - completion has been detected through calls to function MSS_UART_tx_complete(). - NOTE: The MSS_UART_irq_tx() function also enables the Transmitter Holding - Register Empty (THRE) interrupt and the UART instance interrupt in the - Cortex-M3 NVIC as part of its implementation. - - Example: - @code - #include "mss_uart.h" - - int main(void) - { - uint8_t tx_buff[10] = "abcdefghi"; - MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT ); - MSS_UART_irq_tx( &g_mss_uart0, tx_buff, sizeof(tx_buff)); - while ( 0 == MSS_UART_tx_complete( &g_mss_uart0 ) ) - { - ; - } - return(0); - } - @endcode - - @param this_uart - The this_uart parameter is a pointer to an mss_uart_instance_t structure - identifying the MSS UART hardware block that will perform the requested - function. There are two such data structures, g_mss_uart0 and g_mss_uart1, - associated with MSS UART0 and MSS UART1. This parameter must point to either - the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART - driver. - - @param pbuff - The pbuff parameter is a pointer to a buffer containing the data to be - transmitted. - - @param tx_size - The tx_size parameter specifies the size, in bytes, of the data to be - transmitted. - - @return - This function does not return a value. - */ -void -MSS_UART_irq_tx -( - mss_uart_instance_t * this_uart, - const uint8_t * pbuff, - uint32_t tx_size -); - -/***************************************************************************//** - The MSS_UART_tx_complete() function is used to find out if interrupt driven - transmit previously initiated through a call to MSS_UART_irq_tx() is complete. - This is typically used to find out when it is safe to reuse or release the - memory buffer holding transmit data. - - @param this_uart - The this_uart parameter is a pointer to an mss_uart_instance_t structure - identifying the MSS UART hardware block that will perform the requested - function. There are two such data structures, g_mss_uart0 and g_mss_uart1, - associated with MSS UART0 and MSS UART1. This parameter must point to either - the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART - driver. - - @return - This function return a non-zero value if transmit has completed, otherwise - it returns zero. - - Example: - See the MSS_UART_irq_tx() function for an example that uses the - MSS_UART_tx_complete() function. - */ -int8_t -MSS_UART_tx_complete -( - mss_uart_instance_t * this_uart -); - -/***************************************************************************//** - The MSS_UART_get_rx() function is used to read the content of a UART's receive - FIFO. It can be used in polled mode where it is called at regular interval - to find out if any data has been received or in interrupt driven mode where - it is called as part of a receive handler called by the driver as a result of - data being received. This function is non-blocking and will return 0 - immediately if no data has been received. - NOTE: In interrupt driven mode you should call the MSS_UART_get_rx() function - as part of the receive handler function that you register with the MSS UART - driver through a call to MSS_UART_set_rx_handler(). - - @param this_uart - The this_uart parameter is a pointer to an mss_uart_instance_t structure - identifying the MSS UART hardware block that will perform the requested - function. There are two such data structures, g_mss_uart0 and g_mss_uart1, - associated with MSS UART0 and MSS UART1. This parameter must point to either - the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART - driver. - - @param rx_buff - The rx_buff parameter is a pointer to a buffer where the received data will - be copied. - - @param buff_size - The buff_size parameter specifies the size of the receive buffer in bytes. - - @return - This function return the number of bytes that were copied into the rx_buff - buffer. It returns 0 if no data has been received. - - Polled mode example: - @code - int main( void ) - { - uint8_t rx_buff[RX_BUFF_SIZE]; - uint32_t rx_idx = 0; - - MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT ); - - while( 1 ) - { - rx_size = MSS_UART_get_rx( &g_mss_uart0, rx_buff, sizeof(rx_buff) ); - if (rx_size > 0) - { - process_rx_data( rx_buff, rx_size ); - } - task_a(); - task_b(); - } - return 0; - } - @endcode - - Interrupt driven example: - @code - int main( void ) - { - MSS_UART_init( &g_mss_uart1, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT ); - MSS_UART_set_rx_handler( &g_mss_uart1, uart1_rx_handler, MSS_UART_FIFO_SINGLE_BYTE ); - - while( 1 ) - { - task_a(); - task_b(); - } - return 0; - } - - void uart1_rx_handler( void ) - { - uint8_t rx_buff[RX_BUFF_SIZE]; - uint32_t rx_idx = 0; - rx_size = MSS_UART_get_rx( &g_mss_uart1, rx_buff, sizeof(rx_buff) ); - process_rx_data( rx_buff, rx_size ); - } - @endcode - */ -size_t -MSS_UART_get_rx -( - mss_uart_instance_t * this_uart, - uint8_t * rx_buff, - size_t buff_size -); - -/***************************************************************************//** - The MSS_UART_set_rx_handler() function is used to register a receive handler - function which will be called by the driver when a UART Received Data Available - (RDA) interrupt occurs. You must create and register the handler function to - suit your application. The MSS_UART_set_rx_handler() function also enables the UART - Received Data Available interrupt and the UART instance interrupt in the - Cortex-M3 NVIC as part of its implementation. - - @param this_uart - The this_uart parameter is a pointer to an mss_uart_instance_t structure - identifying the MSS UART hardware block that will perform the requested - function. There are two such data structures, g_mss_uart0 and g_mss_uart1, - associated with MSS UART0 and MSS UART1. This parameter must point to either - the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART - driver. - - @param handler - The handler parameter is a pointer to a receive handler function provided - by your application which will be called as a result of a UART Received - Data Available interrupt. - - @param trigger_level - The trigger_level parameter is the receive FIFO trigger level. This specifies - the number of bytes that must be received before the UART triggers a Received - Data Available interrupt. - - @return - This function does not return a value. - - Example: - @code - #include "mss_uart.h" - - #define RX_BUFF_SIZE 64 - - uint8_t g_rx_buff[RX_BUFF_SIZE]; - - void uart0_rx_handler( void ) - { - MSS_UART_get_rx( &g_mss_uart, &g_rx_buff[g_rx_idx], sizeof(g_rx_buff) ); - } - - int main(void) - { - MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT ); - MSS_UART_set_rx_handler( &g_mss_uart0, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE ); - - while ( 1 ) - { - ; - } - return(0); - } - @endcode - */ -void -MSS_UART_set_rx_handler -( - mss_uart_instance_t * this_uart, - mss_uart_rx_handler_t handler, - mss_uart_rx_trig_level_t trigger_level -); - -/***************************************************************************//** - The MSS_UART_set_loopback() function is used to locally loopback the Tx and Rx - lines of a UART. - This is not to be confused with the loopback of UART0 to UART1 which can be - achieved through the microcontroller subsystem's system registers - - @param this_uart - The this_uart parameter is a pointer to an mss_uart_instance_t structure - identifying the MSS UART hardware block that will perform the requested - function. There are two such data structures, g_mss_uart0 and g_mss_uart1, - associated with MSS UART0 and MSS UART1. This parameter must point to either - the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART - driver. - - @param loopback - The loopback parameter indicates whether or not the UART's transmit and receive lines - should be looped back. Allowed values are: - - MSS_UART_LOOPBACK_ON - - MSS_UART_LOOPBACK_OFF - @return - This function does not return a value. - */ -void -MSS_UART_set_loopback -( - mss_uart_instance_t * this_uart, - mss_uart_loopback_t loopback -); - -#ifdef __cplusplus -} -#endif - -#endif /* __MSS_UART_H_ */ diff --git a/Demo/CORTEX_A2F200_SoftConsole/WebServer/httpd-cgi.c b/Demo/CORTEX_A2F200_SoftConsole/WebServer/httpd-cgi.c index 38ea41fa2..4fb459b25 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/WebServer/httpd-cgi.c +++ b/Demo/CORTEX_A2F200_SoftConsole/WebServer/httpd-cgi.c @@ -49,6 +49,7 @@ #include "apps/httpd/httpd.h" #include "apps/httpd/httpd-cgi.h" #include "apps/httpd/httpd-fs.h" +#include "mss_ace.h" #include #include @@ -209,6 +210,9 @@ unsigned long ulString; static unsigned short generate_io_state( void *arg ) { extern long lParTestGetLEDState( unsigned long ulLED ); + unsigned short usRawVoltage; + const ace_channel_handle_t xVoltageChannel = ( ace_channel_handle_t ) 0; + ( void ) arg; /* Are the dynamically setable LEDs currently on or off? */ @@ -221,7 +225,8 @@ static unsigned short generate_io_state( void *arg ) pcStatus = ""; } - sprintf( uip_appdata, "LED

", pcStatus ); + usRawVoltage = ( unsigned short ) ACE_get_ppe_sample( xVoltageChannel ); + sprintf( uip_appdata, "LED

Raw voltage input is %d", pcStatus, usRawVoltage ); return strlen( uip_appdata ); } diff --git a/Demo/CORTEX_A2F200_SoftConsole/main-blinky.c b/Demo/CORTEX_A2F200_SoftConsole/main-blinky.c index 82b48f6e4..cd04278b2 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/main-blinky.c +++ b/Demo/CORTEX_A2F200_SoftConsole/main-blinky.c @@ -185,8 +185,8 @@ int main(void) xTaskCreate( prvQueueReceiveTask, ( signed char * ) "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); - /* Create the software timer that is responsible for turning off the LED - if the button is not pushed within 5000ms, as described at the top of + /* Create the software timer that is responsible for turning off the LED + if the button is not pushed within 5000ms, as described at the top of this file. */ xLEDTimer = xTimerCreate( ( const signed char * ) "LEDTimer", /* A text name, purely to help debugging. */ ( 5000 / portTICK_RATE_MS ), /* The timer period, in this case 5000ms (5s). */ @@ -289,8 +289,8 @@ unsigned long ulReceivedValue; if( ulReceivedValue == 100UL ) { /* NOTE - accessing the LED port should use a critical section - because it is accessed from multiple tasks, and the button interrupt - - in this trivial case, for simplicity, the critical section is + because it is accessed from multiple tasks, and the button interrupt + - in this trivial case, for simplicity, the critical section is omitted. */ if( ( ulGPIOState & mainTASK_CONTROLLED_LED ) != 0 ) { @@ -308,6 +308,8 @@ unsigned long ulReceivedValue; static void prvSetupHardware( void ) { + SystemCoreClockUpdate(); + /* Disable the Watch Dog Timer */ MSS_WD_disable( ); @@ -340,7 +342,7 @@ void vApplicationMallocFailedHook( void ) { /* Called if a call to pvPortMalloc() fails because there is insufficient free memory available in the FreeRTOS heap. pvPortMalloc() is called - internally by FreeRTOS API functions that create tasks, queues, software + internally by FreeRTOS API functions that create tasks, queues, software timers, and semaphores. The size of the FreeRTOS heap is set by the configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ for( ;; ); @@ -364,7 +366,7 @@ void vApplicationIdleHook( void ) volatile size_t xFreeStackSpace; /* This function is called on each cycle of the idle task. In this case it - does nothing useful, other than report the amout of FreeRTOS heap that + does nothing useful, other than report the amout of FreeRTOS heap that remains unallocated. */ xFreeStackSpace = xPortGetFreeHeapSize(); @@ -376,3 +378,21 @@ volatile size_t xFreeStackSpace; reduced accordingly. */ } } +/*-----------------------------------------------------------*/ + +void vMainConfigureTimerForRunTimeStats( void ) +{ + /* This function is not used by the Blinky build configuration, but needs + to be defined as the Blinky and Full build configurations share a + FreeRTOSConfig.h header file. */ +} +/*-----------------------------------------------------------*/ + +unsigned long ulGetRunTimeCounterValue( void ) +{ + /* This function is not used by the Blinky build configuration, but needs + to be defined as the Blinky and Full build configurations share a + FreeRTOSConfig.h header file. */ + return 0UL; +} + diff --git a/Demo/CORTEX_A2F200_SoftConsole/main-full.c b/Demo/CORTEX_A2F200_SoftConsole/main-full.c index cb7eb25ae..d412c41da 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/main-full.c +++ b/Demo/CORTEX_A2F200_SoftConsole/main-full.c @@ -148,6 +148,7 @@ #include "mss_gpio.h" #include "mss_watchdog.h" #include "mss_timer.h" +#include "mss_ace.h" #include "oled.h" /* Common demo includes. */ @@ -551,6 +552,9 @@ static void prvSetupHardware( void ) /* Configure the GPIO for the LEDs. */ vParTestInitialise(); + + /* ACE Initialization */ + ACE_init(); /* Setup the GPIO and the NVIC for the switch used in this simple demo. */ NVIC_SetPriority( GPIO8_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); @@ -628,6 +632,7 @@ const unsigned long ulMax32BitValue = 0xffffffffUL; MSS_TIM64_start(); } /*-----------------------------------------------------------*/ + unsigned long ulGetRunTimeCounterValue( void ) { unsigned long long ullCurrentValue; diff --git a/Demo/CORTEX_A2F200_SoftConsole/uIP_Task.c b/Demo/CORTEX_A2F200_SoftConsole/uIP_Task.c index 3a6ea91e6..2df6fffbe 100644 --- a/Demo/CORTEX_A2F200_SoftConsole/uIP_Task.c +++ b/Demo/CORTEX_A2F200_SoftConsole/uIP_Task.c @@ -159,8 +159,8 @@ clock_time_t clock_time( void ) void vuIP_Task( void *pvParameters ) { portBASE_TYPE i; -unsigned long ulNewEvent = 0UL; -unsigned long ulUIP_Events = 0UL; +unsigned long ulNewEvent = 0UL, ulUIP_Events = 0UL; +long lPacketLength; /* Just to prevent compiler warnings about the unused parameter. */ ( void ) pvParameters; @@ -174,11 +174,13 @@ unsigned long ulUIP_Events = 0UL; for( ;; ) { /* Is there received data ready to be processed? */ - uip_len = MSS_MAC_rx_packet(); + lPacketLength = MSS_MAC_rx_packet(); /* Statements to be executed if data has been received on the Ethernet. */ - if( ( uip_len > 0 ) && ( uip_buf != NULL ) ) + if( ( lPacketLength > 0 ) && ( uip_buf != NULL ) ) { + uip_len = ( u16_t ) lPacketLength; + /* Standard uIP loop taken from the uIP manual. */ if( xHeader->type == htons( UIP_ETHTYPE_IP ) ) { @@ -286,14 +288,14 @@ xTimerHandle xARPTimer, xPeriodicTimer; xEMACEventQueue = xQueueCreate( uipEVENT_QUEUE_LENGTH, sizeof( unsigned long ) ); /* Create and start the uIP timers. */ - xARPTimer = xTimerCreate( ( const signed char * const ) "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */ + xARPTimer = xTimerCreate( ( signed char * ) "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */ ( 10000UL / portTICK_RATE_MS ), /* Timer period. */ pdTRUE, /* Autor-reload. */ ( void * ) uipARP_TIMER, prvUIPTimerCallback ); - xPeriodicTimer = xTimerCreate( ( const signed char * const ) "PeriodicTimer", + xPeriodicTimer = xTimerCreate( ( signed char * ) "PeriodicTimer", ( 500UL / portTICK_RATE_MS ), pdTRUE, /* Autor-reload. */ ( void * ) uipPERIODIC_TIMER, @@ -356,7 +358,7 @@ void vEMACWrite( void ) { const long lMaxAttempts = 10; long lAttempt; -const portTickType xShortDelay = ( 10 / portTICK_RATE_MS ); +const portTickType xShortDelay = ( 5 / portTICK_RATE_MS ); /* Try to send data to the Ethernet. Keep trying for a while if data cannot be sent immediately. Note that this will actually cause the data to be sent