1 /*******************************************************************************
\r
2 * (c) Copyright 2009 Actel Corporation. All rights reserved.
\r
4 * SVN $Revision: 2905 $
\r
5 * SVN $Date: 2010-08-20 14:03:28 +0100 (Fri, 20 Aug 2010) $
\r
9 #include "mtd_data.h"
\r
10 #include "envm_layout.h"
\r
11 #include "mss_ace_configurator.h"
\r
12 #include "../../CMSIS/a2fxxxm3.h"
\r
13 #include "../../CMSIS/mss_assert.h"
\r
14 #include "../../drivers_config/mss_ace/ace_config.h"
\r
21 #define START_ADC_CONVERSION 0x80uL
\r
25 void ace_init_flags( void );
\r
26 void ace_init_convert(void);
\r
28 /*-------------------------------------------------------------------------*//**
\r
29 See "mss_ace.h" for details of how to use this function.
\r
31 void ACE_init( void )
\r
33 /* Initialize driver's internal data. */
\r
34 #if (ACE_NB_OF_PPE_FLAGS > 0)
\r
38 /* Initialize the data structures used by conversion functions. */
\r
42 /*-------------------------------------------------------------------------*//**
\r
43 See "mss_ace.h" for details of how to use this function.
\r
47 adc_channel_id_t channel_id
\r
50 ACE->ADC0_CONV_CTRL = (uint32_t)channel_id | START_ADC_CONVERSION;
\r
53 /*-------------------------------------------------------------------------*//**
\r
54 See "mss_ace.h" for details of how to use this function.
\r
56 #define ADC_DATAVALID_MASK 0x00001000uL
\r
57 #define ADC_RESULT_MASK 0x00000FFFuL
\r
59 static const uint32_t volatile * const adc_status_reg_lut[NB_OF_ANALOG_MODULES] =
\r
66 uint16_t ACE_get_adc_result
\r
71 uint16_t result = 0u;
\r
72 uint32_t data_valid;
\r
74 ASSERT( adc_id < NB_OF_ANALOG_MODULES );
\r
76 if ( adc_id < (uint8_t)NB_OF_ANALOG_MODULES )
\r
79 data_valid = *adc_status_reg_lut[adc_id] & ADC_DATAVALID_MASK;
\r
80 } while ( !data_valid );
\r
82 result = (uint16_t)(*adc_status_reg_lut[adc_id] & ADC_RESULT_MASK);
\r
87 /*==============================================================================
\r
88 =========== Sigma Delta Digital to Analog Converters (SDD) Control ============
\r
89 =============================================================================*/
\r
91 #define SDD_ENABLE_MASK 0x20uL
\r
92 #define SDD_REG_SEL_MASK 0x40uL
\r
94 #define DAC0_SYNC_EN_MASK 0x10uL
\r
95 #define DAC1_SYNC_EN_MASK 0x20uL
\r
96 #define DAC2_SYNC_EN_MASK 0x40uL
\r
98 #define DAC0_SYNC_UPDATE 0x01uL
\r
99 #define DAC1_SYNC_UPDATE 0x02uL
\r
100 #define DAC2_SYNC_UPDATE 0x04uL
\r
102 /*-------------------------------------------------------------------------*//**
\r
105 static volatile uint32_t * const dac_ctrl_reg_lut[NB_OF_ANALOG_MODULES] =
\r
112 static const uint32_t dac_enable_masks_lut[NB_OF_ANALOG_MODULES] =
\r
119 static volatile uint32_t * const dac_byte01_reg_lut[NB_OF_ANALOG_MODULES] =
\r
121 &ACE->SSE_DAC0_BYTES01,
\r
122 &ACE->SSE_DAC1_BYTES01,
\r
123 &ACE->SSE_DAC2_BYTES01,
\r
126 static volatile uint32_t * const dac_byte2_reg_lut[NB_OF_ANALOG_MODULES] =
\r
133 /*------------------------------------------------------------------------------
\r
134 * Pointer to the manufacturing test data containing trimming information
\r
135 * generated during manufacturing.
\r
137 static const mtd_data_t * const p_mtd_data = (mtd_data_t *)MTD_ADDRESS;
\r
139 /*-------------------------------------------------------------------------*//**
\r
140 See "mss_ace.h" for details of how to use this function.
\r
142 #define OBD_MODE_MASK (uint8_t)0x01
\r
143 #define OBD_CHOPPING_MASK (uint8_t)0x02
\r
145 void ACE_configure_sdd
\r
148 sdd_resolution_t resolution,
\r
150 sdd_update_method_t sync_update
\r
153 ASSERT( sdd_id < NB_OF_SDD );
\r
155 if ( sdd_id < NB_OF_SDD )
\r
157 const uint8_t sdd_2_quad_lut[NB_OF_SDD] = {0u, 2u, 4u};
\r
159 uint8_t obd_mode_idx = 1u;
\r
160 uint8_t chopping_mode_idx = 0u;
\r
161 uint32_t saved_pc2_ctrl;
\r
163 quad_id = sdd_2_quad_lut[sdd_id];
\r
165 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
166 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
167 ACE->PC2_CTRL = 0u;
\r
169 /* Select between voltage/current and RTZ modes.*/
\r
170 ACE->ACB_DATA[quad_id].b6 = mode;
\r
172 /* Load manufacturing generated trim value. */
\r
173 if ( (mode & OBD_MODE_MASK) > 0u )
\r
177 if ( (mode & OBD_CHOPPING_MASK) > 0u )
\r
179 chopping_mode_idx = 1u;
\r
181 ACE->ACB_DATA[quad_id].b4
\r
182 = p_mtd_data->odb_trimming[sdd_id][obd_mode_idx][chopping_mode_idx];
\r
184 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
185 * beyond this point. */
\r
186 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
188 /* Set SDD resolution. */
\r
189 *dac_ctrl_reg_lut[sdd_id] = (uint32_t)resolution;
\r
191 /* Update SDD value through SSE_DACn_BYTES01. */
\r
192 *dac_ctrl_reg_lut[sdd_id] |= SDD_REG_SEL_MASK;
\r
194 /* Synchronous or individual SDD update. */
\r
195 if ( INDIVIDUAL_UPDATE == sync_update )
\r
197 ACE->DAC_SYNC_CTRL &= ~dac_enable_masks_lut[sdd_id];
\r
201 ACE->DAC_SYNC_CTRL |= dac_enable_masks_lut[sdd_id];
\r
206 /*-------------------------------------------------------------------------*//**
\r
207 See "mss_ace.h" for details of how to use this function.
\r
209 void ACE_enable_sdd
\r
214 ASSERT( sdd_id < NB_OF_SDD );
\r
216 if ( sdd_id < NB_OF_SDD )
\r
218 *dac_ctrl_reg_lut[sdd_id] |= SDD_ENABLE_MASK;
\r
222 /*-------------------------------------------------------------------------*//**
\r
223 See "mss_ace.h" for details of how to use this function.
\r
225 void ACE_disable_sdd
\r
230 ASSERT( sdd_id < NB_OF_SDD );
\r
232 if ( sdd_id < NB_OF_SDD )
\r
234 *dac_ctrl_reg_lut[sdd_id] &= ~SDD_ENABLE_MASK;
\r
238 /*-------------------------------------------------------------------------*//**
\r
239 See "mss_ace.h" for details of how to use this function.
\r
241 void ACE_set_sdd_value
\r
247 ASSERT( sdd_id < NB_OF_SDD );
\r
249 if ( sdd_id < NB_OF_SDD )
\r
251 *dac_byte2_reg_lut[sdd_id] = sdd_value >> 16;
\r
252 *dac_byte01_reg_lut[sdd_id] = sdd_value;
\r
256 /*-------------------------------------------------------------------------*//**
\r
257 See "mss_ace.h" for details of how to use this function.
\r
259 void ACE_set_sdd_value_sync
\r
261 uint32_t sdd0_value,
\r
262 uint32_t sdd1_value,
\r
263 uint32_t sdd2_value
\r
266 uint32_t dac_sync_ctrl;
\r
268 dac_sync_ctrl = ACE->DAC_SYNC_CTRL;
\r
270 if ( SDD_NO_UPDATE != sdd0_value )
\r
272 ACE->DAC0_BYTE2 = sdd0_value >> 16;
\r
273 ACE->SSE_DAC0_BYTES01 = sdd0_value;
\r
274 dac_sync_ctrl |= DAC0_SYNC_UPDATE;
\r
277 if ( SDD_NO_UPDATE != sdd1_value )
\r
279 ACE->DAC1_BYTE2 = sdd1_value >> 16;
\r
280 ACE->SSE_DAC1_BYTES01 = sdd1_value;
\r
281 dac_sync_ctrl |= DAC1_SYNC_UPDATE;
\r
284 if ( SDD_NO_UPDATE != sdd2_value )
\r
286 ACE->DAC2_BYTE2 = sdd2_value >> 16;
\r
287 ACE->DAC2_BYTE1 = sdd2_value >> 8;
\r
288 ACE->SSE_DAC2_BYTES01 = sdd2_value;
\r
289 dac_sync_ctrl |= DAC2_SYNC_UPDATE;
\r
292 ACE->DAC_SYNC_CTRL = dac_sync_ctrl;
\r
295 /*==============================================================================
\r
296 ============================ Comparators Control ==============================
\r
297 =============================================================================*/
\r
300 * SDD Analog switch mask. ACB byte 10.
\r
301 * 0: TMB comparator reference voltage is an ADC direct input
\r
302 * 1: TMB comparator reference voltage is one of the SDD outputs as
\r
303 * selected by DAC_MUXSEL[1:0]
\r
305 #define B10_COMP_VREF_SW_MASK 0x20u
\r
308 * Comparator reference voltage multiplexer.
\r
309 * Used to select which SDD output will be used as reference voltage for TMB
\r
310 * comparator. These bits are only meaningful when COMP_VREF_SW is set to 1.
\r
312 #define B11_DAC_MUXSEL_MASK 0x03u
\r
315 * Number of bits to shift a value of type comp_hysteresis_t to get the
\r
316 * hysteresis to program into ACB b9 or b10.
\r
318 #define HYSTERESIS_SHIFT 6u
\r
321 * Mask of hysteresis bits within ACB b9 or b10.
\r
323 #define HYSTERESIS_MASK 0xC0u
\r
326 * Mask of the comparator enable bit within ACB b9 and b10.
\r
328 #define COMPARATOR_ENABLE_MASK 0x10u
\r
331 * Comparator ID to Signal Conditioning Block (SCB) lookup table.
\r
332 * USe to find which SCB a comparator belongs to.
\r
334 const uint8_t comp_id_2_scb_lut[NB_OF_COMPARATORS] =
\r
350 /*-------------------------------------------------------------------------*//**
\r
351 * This function is requred to configure comparators included in temperature
\r
354 void ACE_set_comp_reference
\r
356 comparator_id_t comp_id,
\r
357 comp_reference_t reference
\r
363 odd = (uint32_t)comp_id & 0x01uL;
\r
365 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
366 ASSERT( reference < NB_OF_COMP_REF );
\r
367 ASSERT( odd ); /* Only Temperature block comparators have configurable reference input. */
\r
369 if ( (comp_id < NB_OF_COMPARATORS) && (reference < NB_OF_COMP_REF) && (odd) )
\r
371 uint32_t saved_pc2_ctrl;
\r
373 scb_id = comp_id_2_scb_lut[comp_id];
\r
375 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
376 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
377 ACE->PC2_CTRL = 0u;
\r
379 if ( ADC_IN_COMP_REF == reference )
\r
381 ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK;
\r
382 ACE->ACB_DATA[scb_id].b11 &= (uint8_t)~B11_DAC_MUXSEL_MASK;
\r
386 ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK;
\r
387 ACE->ACB_DATA[scb_id].b11 = (ACE->ACB_DATA[scb_id].b11 & (uint8_t)~B11_DAC_MUXSEL_MASK) + (uint8_t)reference;
\r
390 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
391 * beyond this point. */
\r
392 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
396 /*-------------------------------------------------------------------------*//**
\r
397 * Set analog block comparators hysteresis.
\r
399 void ACE_set_comp_hysteresis
\r
401 comparator_id_t comp_id,
\r
402 comp_hysteresis_t hysteresis
\r
407 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
408 ASSERT( hysteresis < NB_OF_HYSTERESIS );
\r
410 if ( (comp_id < NB_OF_COMPARATORS) && (hysteresis < NB_OF_HYSTERESIS) )
\r
413 uint32_t saved_pc2_ctrl;
\r
415 scb_id = comp_id_2_scb_lut[comp_id];
\r
416 odd = (uint32_t)comp_id & 0x01uL;
\r
418 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
419 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
420 ACE->PC2_CTRL = 0u;
\r
424 /* Temperature monitor block comparator. */
\r
425 ACE->ACB_DATA[scb_id].b10 = (ACE->ACB_DATA[scb_id].b10 & HYSTERESIS_MASK) | (uint8_t)((uint8_t)hysteresis << HYSTERESIS_SHIFT);
\r
429 /* Current monitor block comparator. */
\r
430 ACE->ACB_DATA[scb_id].b9 = (ACE->ACB_DATA[scb_id].b9 & HYSTERESIS_MASK) | (uint8_t)((uint8_t)hysteresis << HYSTERESIS_SHIFT);
\r
433 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
434 * beyond this point. */
\r
435 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
439 /*-------------------------------------------------------------------------*//**
\r
442 void ACE_enable_comp
\r
444 comparator_id_t comp_id
\r
449 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
451 if ( comp_id < NB_OF_COMPARATORS )
\r
454 uint32_t saved_pc2_ctrl;
\r
456 scb_id = comp_id_2_scb_lut[comp_id];
\r
457 odd = (uint32_t)comp_id & 0x01uL;
\r
459 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
460 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
461 ACE->PC2_CTRL = 0u;
\r
465 /* Temperature monitor block comparator. */
\r
466 ACE->ACB_DATA[scb_id].b10 |= COMPARATOR_ENABLE_MASK;
\r
470 /* Current monitor block comparator. */
\r
471 ACE->ACB_DATA[scb_id].b9 |= COMPARATOR_ENABLE_MASK;
\r
474 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
475 * beyond this point. */
\r
476 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
480 /*-------------------------------------------------------------------------*//**
\r
483 void ACE_disable_comp
\r
485 comparator_id_t comp_id
\r
490 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
492 if ( comp_id < NB_OF_COMPARATORS )
\r
495 uint32_t saved_pc2_ctrl;
\r
497 scb_id = comp_id_2_scb_lut[comp_id];
\r
498 odd = (uint32_t)comp_id & 0x01uL;
\r
500 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
501 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
502 ACE->PC2_CTRL = 0u;
\r
506 /* Temperature monitor block comparator. */
\r
507 ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~COMPARATOR_ENABLE_MASK;
\r
511 /* Current monitor block comparator. */
\r
512 ACE->ACB_DATA[scb_id].b9 &= (uint8_t)~COMPARATOR_ENABLE_MASK;
\r
515 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
516 * beyond this point. */
\r
517 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
522 * Bit mask of comparator 0 rise interrupt bit.
\r
523 * Shift this value left by the value of the comparator ID to obtain the bit
\r
524 * mask used enable/disable/clear rise interrupts from that comparator.
\r
526 #define FIRST_RISE_IRQ_MASK 0x00000800uL
\r
529 * Bit mask of comparator 0 fall interrupt bit.
\r
530 * Shift this value left by the value of the comparator ID to obtain the bit
\r
531 * mask used enable/disable/clear fall interrupts from that comparator.
\r
533 #define FIRST_FALL_IRQ_MASK 0x00000001uL
\r
535 /*-------------------------------------------------------------------------*//**
\r
536 See "mss_ace.h" for details of how to use this function.
\r
538 void ACE_enable_comp_rise_irq
\r
540 comparator_id_t comp_id
\r
543 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
545 ACE->COMP_IRQ_EN |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id);
\r
548 /*-------------------------------------------------------------------------*//**
\r
549 See "mss_ace.h" for details of how to use this function.
\r
551 void ACE_disable_comp_rise_irq
\r
553 comparator_id_t comp_id
\r
556 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
558 ACE->COMP_IRQ_EN &= ~(FIRST_RISE_IRQ_MASK << (uint32_t)comp_id);
\r
561 /*-------------------------------------------------------------------------*//**
\r
562 See "mss_ace.h" for details of how to use this function.
\r
564 void ACE_clear_comp_rise_irq
\r
566 comparator_id_t comp_id
\r
569 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
571 ACE->COMP_IRQ_CLR |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id);
\r
574 /*-------------------------------------------------------------------------*//**
\r
575 See "mss_ace.h" for details of how to use this function.
\r
577 void ACE_enable_comp_fall_irq
\r
579 comparator_id_t comp_id
\r
582 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
584 ACE->COMP_IRQ_EN |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id);
\r
587 /*-------------------------------------------------------------------------*//**
\r
588 See "mss_ace.h" for details of how to use this function.
\r
590 void ACE_disable_comp_fall_irq
\r
592 comparator_id_t comp_id
\r
595 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
597 ACE->COMP_IRQ_EN &= ~(FIRST_FALL_IRQ_MASK << (uint32_t)comp_id);
\r
600 /*-------------------------------------------------------------------------*//**
\r
601 See "mss_ace.h" for details of how to use this function.
\r
603 void ACE_clear_comp_fall_irq
\r
605 comparator_id_t comp_id
\r
608 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
610 ACE->COMP_IRQ_CLR |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id);
\r
613 /*-------------------------------------------------------------------------*//**
\r
614 * Returns the raw analog quad comparator status.
\r
616 uint32_t ACE_get_comp_status( void )
\r
618 return ACE->COMP_IRQ;
\r
621 /*==============================================================================
\r
622 ============ Reading Samples from post processing engine (PPE) ================
\r
623 =============================================================================*/
\r
624 extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS];
\r
626 /*-------------------------------------------------------------------------*//**
\r
627 See "mss_ace.h" for details of how to use this function.
\r
630 ACE_get_channel_count
\r
635 return (uint32_t)ACE_NB_OF_INPUT_CHANNELS;
\r
638 /*-------------------------------------------------------------------------*//**
\r
639 See "mss_ace.h" for details of how to use this function.
\r
641 ace_channel_handle_t
\r
642 ACE_get_first_channel
\r
647 ace_channel_handle_t channel_handle;
\r
649 channel_handle = (ace_channel_handle_t)0;
\r
651 return channel_handle;
\r
654 /*-------------------------------------------------------------------------*//**
\r
655 See "mss_ace.h" for details of how to use this function.
\r
657 ace_channel_handle_t
\r
658 ACE_get_next_channel
\r
660 ace_channel_handle_t channel_handle
\r
665 if ( channel_handle >= NB_OF_ACE_CHANNEL_HANDLES )
\r
667 channel_handle = (ace_channel_handle_t)0;
\r
670 return channel_handle;
\r
673 /*-------------------------------------------------------------------------*//**
\r
674 See "mss_ace.h" for details of how to use this function.
\r
676 ace_channel_handle_t
\r
677 ACE_get_channel_handle
\r
679 const uint8_t * p_sz_channel_name
\r
682 uint16_t channel_idx;
\r
683 ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE;
\r
685 for ( channel_idx = 0u; channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx )
\r
687 if ( g_ace_channel_desc_table[channel_idx].p_sz_channel_name != 0 )
\r
690 diff = strncmp( (const char*)p_sz_channel_name, (const char*)g_ace_channel_desc_table[channel_idx].p_sz_channel_name, MAX_CHANNEL_NAME_LENGTH );
\r
693 /* channel name found. */
\r
694 channel_handle = (ace_channel_handle_t)channel_idx;
\r
699 return channel_handle;
\r
702 /*-------------------------------------------------------------------------*//**
\r
703 See "mss_ace.h" for details of how to use this function.
\r
705 ace_channel_handle_t
\r
706 ACE_get_input_channel_handle
\r
708 adc_channel_id_t channel_id
\r
711 uint16_t channel_idx;
\r
712 ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE;
\r
714 for ( channel_idx = 0u; channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx )
\r
716 if ( g_ace_channel_desc_table[channel_idx].signal_id == channel_id )
\r
718 /* channel ID found. */
\r
719 channel_handle = (ace_channel_handle_t)channel_idx;
\r
723 return channel_handle;
\r
726 /*-------------------------------------------------------------------------*//**
\r
727 See "mss_ace.h" for details of how to use this function.
\r
732 ace_channel_handle_t channel_handle
\r
736 uint16_t ppe_offset;
\r
738 ppe_offset = g_ace_channel_desc_table[channel_handle].signal_ppe_offset;
\r
739 sample = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset] >> 16u);
\r