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
36 /* Initialize the data structures used by conversion functions. */
\r
40 /*-------------------------------------------------------------------------*//**
\r
41 See "mss_ace.h" for details of how to use this function.
\r
45 adc_channel_id_t channel_id
\r
48 ACE->ADC0_CONV_CTRL = (uint32_t)channel_id | START_ADC_CONVERSION;
\r
51 /*-------------------------------------------------------------------------*//**
\r
52 See "mss_ace.h" for details of how to use this function.
\r
54 #define ADC_DATAVALID_MASK 0x00001000uL
\r
55 #define ADC_RESULT_MASK 0x00000FFFuL
\r
57 static const uint32_t volatile * const adc_status_reg_lut[NB_OF_ANALOG_MODULES] =
\r
64 uint16_t ACE_get_adc_result
\r
69 uint16_t result = 0u;
\r
70 uint32_t data_valid;
\r
72 ASSERT( adc_id < NB_OF_ANALOG_MODULES );
\r
74 if ( adc_id < (uint8_t)NB_OF_ANALOG_MODULES )
\r
77 data_valid = *adc_status_reg_lut[adc_id] & ADC_DATAVALID_MASK;
\r
78 } while ( !data_valid );
\r
80 result = (uint16_t)(*adc_status_reg_lut[adc_id] & ADC_RESULT_MASK);
\r
85 /*==============================================================================
\r
86 =========== Sigma Delta Digital to Analog Converters (SDD) Control ============
\r
87 =============================================================================*/
\r
89 #define SDD_ENABLE_MASK 0x20uL
\r
90 #define SDD_REG_SEL_MASK 0x40uL
\r
92 #define DAC0_SYNC_EN_MASK 0x10uL
\r
93 #define DAC1_SYNC_EN_MASK 0x20uL
\r
94 #define DAC2_SYNC_EN_MASK 0x40uL
\r
96 #define DAC0_SYNC_UPDATE 0x01uL
\r
97 #define DAC1_SYNC_UPDATE 0x02uL
\r
98 #define DAC2_SYNC_UPDATE 0x04uL
\r
100 /*-------------------------------------------------------------------------*//**
\r
103 static volatile uint32_t * const dac_ctrl_reg_lut[NB_OF_ANALOG_MODULES] =
\r
110 static const uint32_t dac_enable_masks_lut[NB_OF_ANALOG_MODULES] =
\r
117 static volatile uint32_t * const dac_byte01_reg_lut[NB_OF_ANALOG_MODULES] =
\r
119 &ACE->SSE_DAC0_BYTES01,
\r
120 &ACE->SSE_DAC1_BYTES01,
\r
121 &ACE->SSE_DAC2_BYTES01,
\r
124 static volatile uint32_t * const dac_byte2_reg_lut[NB_OF_ANALOG_MODULES] =
\r
131 /*------------------------------------------------------------------------------
\r
132 * Pointer to the manufacturing test data containing trimming information
\r
133 * generated during manufacturing.
\r
135 static const mtd_data_t * const p_mtd_data = (mtd_data_t *)MTD_ADDRESS;
\r
137 /*-------------------------------------------------------------------------*//**
\r
138 See "mss_ace.h" for details of how to use this function.
\r
140 #define OBD_MODE_MASK (uint8_t)0x01
\r
141 #define OBD_CHOPPING_MASK (uint8_t)0x02
\r
143 void ACE_configure_sdd
\r
146 sdd_resolution_t resolution,
\r
148 sdd_update_method_t sync_update
\r
151 ASSERT( sdd_id < NB_OF_SDD );
\r
153 if ( sdd_id < NB_OF_SDD )
\r
155 const uint8_t sdd_2_quad_lut[NB_OF_SDD] = {0u, 2u, 4u};
\r
157 uint8_t obd_mode_idx = 1u;
\r
158 uint8_t chopping_mode_idx = 0u;
\r
159 uint32_t saved_pc2_ctrl;
\r
161 quad_id = sdd_2_quad_lut[sdd_id];
\r
163 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
164 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
165 ACE->PC2_CTRL = 0u;
\r
167 /* Select between voltage/current and RTZ modes.*/
\r
168 ACE->ACB_DATA[quad_id].b6 = mode;
\r
170 /* Load manufacturing generated trim value. */
\r
171 if ( (mode & OBD_MODE_MASK) > 0u )
\r
175 if ( (mode & OBD_CHOPPING_MASK) > 0u )
\r
177 chopping_mode_idx = 1u;
\r
179 ACE->ACB_DATA[quad_id].b4
\r
180 = p_mtd_data->odb_trimming[sdd_id][obd_mode_idx][chopping_mode_idx];
\r
182 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
183 * beyond this point. */
\r
184 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
186 /* Set SDD resolution. */
\r
187 *dac_ctrl_reg_lut[sdd_id] = (uint32_t)resolution;
\r
189 /* Update SDD value through SSE_DACn_BYTES01. */
\r
190 *dac_ctrl_reg_lut[sdd_id] |= SDD_REG_SEL_MASK;
\r
192 /* Synchronous or individual SDD update. */
\r
193 if ( INDIVIDUAL_UPDATE == sync_update )
\r
195 ACE->DAC_SYNC_CTRL &= ~dac_enable_masks_lut[sdd_id];
\r
199 ACE->DAC_SYNC_CTRL |= dac_enable_masks_lut[sdd_id];
\r
204 /*-------------------------------------------------------------------------*//**
\r
205 See "mss_ace.h" for details of how to use this function.
\r
207 void ACE_enable_sdd
\r
212 ASSERT( sdd_id < NB_OF_SDD );
\r
214 if ( sdd_id < NB_OF_SDD )
\r
216 *dac_ctrl_reg_lut[sdd_id] |= SDD_ENABLE_MASK;
\r
220 /*-------------------------------------------------------------------------*//**
\r
221 See "mss_ace.h" for details of how to use this function.
\r
223 void ACE_disable_sdd
\r
228 ASSERT( sdd_id < NB_OF_SDD );
\r
230 if ( sdd_id < NB_OF_SDD )
\r
232 *dac_ctrl_reg_lut[sdd_id] &= ~SDD_ENABLE_MASK;
\r
236 /*-------------------------------------------------------------------------*//**
\r
237 See "mss_ace.h" for details of how to use this function.
\r
239 void ACE_set_sdd_value
\r
245 ASSERT( sdd_id < NB_OF_SDD );
\r
247 if ( sdd_id < NB_OF_SDD )
\r
249 *dac_byte2_reg_lut[sdd_id] = sdd_value >> 16;
\r
250 *dac_byte01_reg_lut[sdd_id] = sdd_value;
\r
254 /*-------------------------------------------------------------------------*//**
\r
255 See "mss_ace.h" for details of how to use this function.
\r
257 void ACE_set_sdd_value_sync
\r
259 uint32_t sdd0_value,
\r
260 uint32_t sdd1_value,
\r
261 uint32_t sdd2_value
\r
264 uint32_t dac_sync_ctrl;
\r
266 dac_sync_ctrl = ACE->DAC_SYNC_CTRL;
\r
268 if ( SDD_NO_UPDATE != sdd0_value )
\r
270 ACE->DAC0_BYTE2 = sdd0_value >> 16;
\r
271 ACE->SSE_DAC0_BYTES01 = sdd0_value;
\r
272 dac_sync_ctrl |= DAC0_SYNC_UPDATE;
\r
275 if ( SDD_NO_UPDATE != sdd1_value )
\r
277 ACE->DAC1_BYTE2 = sdd1_value >> 16;
\r
278 ACE->SSE_DAC1_BYTES01 = sdd1_value;
\r
279 dac_sync_ctrl |= DAC1_SYNC_UPDATE;
\r
282 if ( SDD_NO_UPDATE != sdd2_value )
\r
284 ACE->DAC2_BYTE2 = sdd2_value >> 16;
\r
285 ACE->DAC2_BYTE1 = sdd2_value >> 8;
\r
286 ACE->SSE_DAC2_BYTES01 = sdd2_value;
\r
287 dac_sync_ctrl |= DAC2_SYNC_UPDATE;
\r
290 ACE->DAC_SYNC_CTRL = dac_sync_ctrl;
\r
293 /*==============================================================================
\r
294 ============================ Comparators Control ==============================
\r
295 =============================================================================*/
\r
298 * SDD Analog switch mask. ACB byte 10.
\r
299 * 0: TMB comparator reference voltage is an ADC direct input
\r
300 * 1: TMB comparator reference voltage is one of the SDD outputs as
\r
301 * selected by DAC_MUXSEL[1:0]
\r
303 #define B10_COMP_VREF_SW_MASK 0x20u
\r
306 * Comparator reference voltage multiplexer.
\r
307 * Used to select which SDD output will be used as reference voltage for TMB
\r
308 * comparator. These bits are only meaningful when COMP_VREF_SW is set to 1.
\r
310 #define B11_DAC_MUXSEL_MASK 0x03u
\r
313 * Number of bits to shift a value of type comp_hysteresis_t to get the
\r
314 * hysteresis to program into ACB b9 or b10.
\r
316 #define HYSTERESIS_SHIFT 6u
\r
319 * Mask of hysteresis bits within ACB b9 or b10.
\r
321 #define HYSTERESIS_MASK 0xC0u
\r
324 * Mask of the comparator enable bit within ACB b9 and b10.
\r
326 #define COMPARATOR_ENABLE_MASK 0x10u
\r
329 * Comparator ID to Signal Conditioning Block (SCB) lookup table.
\r
330 * USe to find which SCB a comparator belongs to.
\r
332 const uint8_t comp_id_2_scb_lut[NB_OF_COMPARATORS] =
\r
348 /*-------------------------------------------------------------------------*//**
\r
349 * This function is requred to configure comparators included in temperature
\r
352 void ACE_set_comp_reference
\r
354 comparator_id_t comp_id,
\r
355 comp_reference_t reference
\r
361 odd = (uint32_t)comp_id & 0x01uL;
\r
363 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
364 ASSERT( reference < NB_OF_COMP_REF );
\r
365 ASSERT( odd ); /* Only Temperature block comparators have configurable reference input. */
\r
367 if ( (comp_id < NB_OF_COMPARATORS) && (reference < NB_OF_COMP_REF) && (odd) )
\r
369 uint32_t saved_pc2_ctrl;
\r
371 scb_id = comp_id_2_scb_lut[comp_id];
\r
373 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
374 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
375 ACE->PC2_CTRL = 0u;
\r
377 if ( ADC_IN_COMP_REF == reference )
\r
379 ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK;
\r
380 ACE->ACB_DATA[scb_id].b11 &= (uint8_t)~B11_DAC_MUXSEL_MASK;
\r
384 ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~B10_COMP_VREF_SW_MASK;
\r
385 ACE->ACB_DATA[scb_id].b11 = (ACE->ACB_DATA[scb_id].b11 & (uint8_t)~B11_DAC_MUXSEL_MASK) + (uint8_t)reference;
\r
388 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
389 * beyond this point. */
\r
390 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
394 /*-------------------------------------------------------------------------*//**
\r
395 * Set analog block comparators hysteresis.
\r
397 void ACE_set_comp_hysteresis
\r
399 comparator_id_t comp_id,
\r
400 comp_hysteresis_t hysteresis
\r
405 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
406 ASSERT( hysteresis < NB_OF_HYSTERESIS );
\r
408 if ( (comp_id < NB_OF_COMPARATORS) && (hysteresis < NB_OF_HYSTERESIS) )
\r
411 uint32_t saved_pc2_ctrl;
\r
413 scb_id = comp_id_2_scb_lut[comp_id];
\r
414 odd = (uint32_t)comp_id & 0x01uL;
\r
416 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
417 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
418 ACE->PC2_CTRL = 0u;
\r
422 /* Temperature monitor block comparator. */
\r
423 ACE->ACB_DATA[scb_id].b10 = (ACE->ACB_DATA[scb_id].b10 & HYSTERESIS_MASK) | (uint8_t)((uint8_t)hysteresis << HYSTERESIS_SHIFT);
\r
427 /* Current monitor block comparator. */
\r
428 ACE->ACB_DATA[scb_id].b9 = (ACE->ACB_DATA[scb_id].b9 & HYSTERESIS_MASK) | (uint8_t)((uint8_t)hysteresis << HYSTERESIS_SHIFT);
\r
431 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
432 * beyond this point. */
\r
433 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
437 /*-------------------------------------------------------------------------*//**
\r
440 void ACE_enable_comp
\r
442 comparator_id_t comp_id
\r
447 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
449 if ( comp_id < NB_OF_COMPARATORS )
\r
452 uint32_t saved_pc2_ctrl;
\r
454 scb_id = comp_id_2_scb_lut[comp_id];
\r
455 odd = (uint32_t)comp_id & 0x01uL;
\r
457 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
458 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
459 ACE->PC2_CTRL = 0u;
\r
463 /* Temperature monitor block comparator. */
\r
464 ACE->ACB_DATA[scb_id].b10 |= COMPARATOR_ENABLE_MASK;
\r
468 /* Current monitor block comparator. */
\r
469 ACE->ACB_DATA[scb_id].b9 |= COMPARATOR_ENABLE_MASK;
\r
472 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
473 * beyond this point. */
\r
474 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
478 /*-------------------------------------------------------------------------*//**
\r
481 void ACE_disable_comp
\r
483 comparator_id_t comp_id
\r
488 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
490 if ( comp_id < NB_OF_COMPARATORS )
\r
493 uint32_t saved_pc2_ctrl;
\r
495 scb_id = comp_id_2_scb_lut[comp_id];
\r
496 odd = (uint32_t)comp_id & 0x01uL;
\r
498 /* Pause the SSE PC2 while accesses to ACB from APB3 are taking place. */
\r
499 saved_pc2_ctrl = ACE->PC2_CTRL;
\r
500 ACE->PC2_CTRL = 0u;
\r
504 /* Temperature monitor block comparator. */
\r
505 ACE->ACB_DATA[scb_id].b10 &= (uint8_t)~COMPARATOR_ENABLE_MASK;
\r
509 /* Current monitor block comparator. */
\r
510 ACE->ACB_DATA[scb_id].b9 &= (uint8_t)~COMPARATOR_ENABLE_MASK;
\r
513 /* Restore SSE PC2 operations since no ACB accesses should take place
\r
514 * beyond this point. */
\r
515 ACE->PC2_CTRL = saved_pc2_ctrl;
\r
520 * Bit mask of comparator 0 rise interrupt bit.
\r
521 * Shift this value left by the value of the comparator ID to obtain the bit
\r
522 * mask used enable/disable/clear rise interrupts from that comparator.
\r
524 #define FIRST_RISE_IRQ_MASK 0x00000800uL
\r
527 * Bit mask of comparator 0 fall interrupt bit.
\r
528 * Shift this value left by the value of the comparator ID to obtain the bit
\r
529 * mask used enable/disable/clear fall interrupts from that comparator.
\r
531 #define FIRST_FALL_IRQ_MASK 0x00000001uL
\r
533 /*-------------------------------------------------------------------------*//**
\r
534 See "mss_ace.h" for details of how to use this function.
\r
536 void ACE_enable_comp_rise_irq
\r
538 comparator_id_t comp_id
\r
541 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
543 ACE->COMP_IRQ_EN |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id);
\r
546 /*-------------------------------------------------------------------------*//**
\r
547 See "mss_ace.h" for details of how to use this function.
\r
549 void ACE_disable_comp_rise_irq
\r
551 comparator_id_t comp_id
\r
554 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
556 ACE->COMP_IRQ_EN &= ~(FIRST_RISE_IRQ_MASK << (uint32_t)comp_id);
\r
559 /*-------------------------------------------------------------------------*//**
\r
560 See "mss_ace.h" for details of how to use this function.
\r
562 void ACE_clear_comp_rise_irq
\r
564 comparator_id_t comp_id
\r
567 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
569 ACE->COMP_IRQ_CLR |= (FIRST_RISE_IRQ_MASK << (uint32_t)comp_id);
\r
572 /*-------------------------------------------------------------------------*//**
\r
573 See "mss_ace.h" for details of how to use this function.
\r
575 void ACE_enable_comp_fall_irq
\r
577 comparator_id_t comp_id
\r
580 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
582 ACE->COMP_IRQ_EN |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id);
\r
585 /*-------------------------------------------------------------------------*//**
\r
586 See "mss_ace.h" for details of how to use this function.
\r
588 void ACE_disable_comp_fall_irq
\r
590 comparator_id_t comp_id
\r
593 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
595 ACE->COMP_IRQ_EN &= ~(FIRST_FALL_IRQ_MASK << (uint32_t)comp_id);
\r
598 /*-------------------------------------------------------------------------*//**
\r
599 See "mss_ace.h" for details of how to use this function.
\r
601 void ACE_clear_comp_fall_irq
\r
603 comparator_id_t comp_id
\r
606 ASSERT( comp_id < NB_OF_COMPARATORS );
\r
608 ACE->COMP_IRQ_CLR |= (FIRST_FALL_IRQ_MASK << (uint32_t)comp_id);
\r
611 /*-------------------------------------------------------------------------*//**
\r
612 * Returns the raw analog quad comparator status.
\r
614 uint32_t ACE_get_comp_status( void )
\r
616 return ACE->COMP_IRQ;
\r
619 /*==============================================================================
\r
620 ============ Reading Samples from post processing engine (PPE) ================
\r
621 =============================================================================*/
\r
622 extern ace_channel_desc_t g_ace_channel_desc_table[ACE_NB_OF_INPUT_CHANNELS];
\r
624 /*-------------------------------------------------------------------------*//**
\r
625 See "mss_ace.h" for details of how to use this function.
\r
628 ACE_get_channel_count
\r
633 return (uint32_t)ACE_NB_OF_INPUT_CHANNELS;
\r
636 /*-------------------------------------------------------------------------*//**
\r
637 See "mss_ace.h" for details of how to use this function.
\r
639 ace_channel_handle_t
\r
640 ACE_get_first_channel
\r
645 ace_channel_handle_t channel_handle;
\r
647 channel_handle = (ace_channel_handle_t)0;
\r
649 return channel_handle;
\r
652 /*-------------------------------------------------------------------------*//**
\r
653 See "mss_ace.h" for details of how to use this function.
\r
655 ace_channel_handle_t
\r
656 ACE_get_next_channel
\r
658 ace_channel_handle_t channel_handle
\r
663 if ( channel_handle >= NB_OF_ACE_CHANNEL_HANDLES )
\r
665 channel_handle = (ace_channel_handle_t)0;
\r
668 return channel_handle;
\r
671 /*-------------------------------------------------------------------------*//**
\r
672 See "mss_ace.h" for details of how to use this function.
\r
674 ace_channel_handle_t
\r
675 ACE_get_channel_handle
\r
677 const uint8_t * p_sz_channel_name
\r
680 uint16_t channel_idx;
\r
681 ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE;
\r
683 for ( channel_idx = 0u; channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx )
\r
685 if ( g_ace_channel_desc_table[channel_idx].p_sz_channel_name != 0 )
\r
688 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
691 /* channel name found. */
\r
692 channel_handle = (ace_channel_handle_t)channel_idx;
\r
697 return channel_handle;
\r
700 /*-------------------------------------------------------------------------*//**
\r
701 See "mss_ace.h" for details of how to use this function.
\r
703 ace_channel_handle_t
\r
704 ACE_get_input_channel_handle
\r
706 adc_channel_id_t channel_id
\r
709 uint16_t channel_idx;
\r
710 ace_channel_handle_t channel_handle = INVALID_CHANNEL_HANDLE;
\r
712 for ( channel_idx = 0u; channel_idx < (uint16_t)ACE_NB_OF_INPUT_CHANNELS; ++channel_idx )
\r
714 if ( g_ace_channel_desc_table[channel_idx].signal_id == channel_id )
\r
716 /* channel ID found. */
\r
717 channel_handle = (ace_channel_handle_t)channel_idx;
\r
721 return channel_handle;
\r
724 /*-------------------------------------------------------------------------*//**
\r
725 See "mss_ace.h" for details of how to use this function.
\r
730 ace_channel_handle_t channel_handle
\r
734 uint16_t ppe_offset;
\r
736 ppe_offset = g_ace_channel_desc_table[channel_handle].signal_ppe_offset;
\r
737 sample = (uint16_t)(ACE->PPE_RAM_DATA[ppe_offset] >> 16u);
\r