266 lines
8.2 KiB
C
266 lines
8.2 KiB
C
/*******************************************************************************
|
|
* *
|
|
* Copyright 2012 Rheinmetall Canada Inc. *
|
|
* *
|
|
* No part of this document may be reproduced, stored in *
|
|
* a retrieval system, or transmitted, in any form or by any means, *
|
|
* electronic, mechanical, photocopying, recording, or otherwise, *
|
|
* without the prior written permission of Rheinmetall Canada Inc. *
|
|
* *
|
|
*******************************************************************************/
|
|
/*
|
|
Description:
|
|
This is a template file for standard C header file.
|
|
|
|
*/
|
|
|
|
/* ************************************************************************** */
|
|
/* Revision:
|
|
### 20120521 JFM
|
|
Original version.
|
|
|
|
### YYYYMMDD Initial, Bug Identification
|
|
Change description.
|
|
*/
|
|
|
|
/* ************************************************************************** */
|
|
/* Includes */
|
|
#include "define.h"
|
|
#include "ADC.h"
|
|
#include "HallAcquisition.h"
|
|
#include "digitalio.h"
|
|
#include "PAStatus.h"
|
|
|
|
/* Globals */
|
|
unsigned int guiADCMode;
|
|
unsigned short egADCMotPhaseA;
|
|
unsigned short egADCMotPhaseB;
|
|
unsigned short egADCMotPhaseC;
|
|
|
|
/* Implementation */
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
void InitADC(void)
|
|
{
|
|
//At boot, init ADC in normal mode...
|
|
guiADCMode = ADC_NORMAL_MODE;
|
|
|
|
//configure input pins as analog inputs.
|
|
TRISBbits.TRISB3 = 1;
|
|
AD1PCFGbits.PCFG3 = 0;
|
|
TRISBbits.TRISB4 = 1;
|
|
AD1PCFGbits.PCFG4 = 0;
|
|
TRISBbits.TRISB5 = 1;
|
|
AD1PCFGbits.PCFG5 = 0;
|
|
TRISBbits.TRISB8 = 1;
|
|
AD1PCFGbits.PCFG8 = 0;
|
|
TRISBbits.TRISB9 = 1;
|
|
AD1PCFGbits.PCFG9 = 0;
|
|
TRISBbits.TRISB11 = 1;
|
|
AD1PCFGbits.PCFG11 = 0;
|
|
TRISBbits.TRISB12 = 1;
|
|
AD1PCFGbits.PCFG12 = 0;
|
|
TRISBbits.TRISB13 = 1;
|
|
AD1PCFGbits.PCFG13 = 0;
|
|
|
|
AD1CON1 = 0;
|
|
AD1CON2 = 0;
|
|
AD1CON3 = 0;
|
|
|
|
//configure output format (unsigned int 16 bits)
|
|
AD1CON1bits.FORM = 0b000;
|
|
//configure clock source and prescaling
|
|
AD1CON3bits.ADRC = 0; //Use Peripheral clock
|
|
AD1CON3bits.ADCS = 4; //Acording to datasheet TAD must be min 83.33ns --> minimal prescaler applied to TPBclk = 8 --> Conversion time ~= 100ns
|
|
//AD1CON3bits.SAMC = 1; //Used in automatic sampling mode (scan mode). Shall be augmented if results are not accurate. See datasheet.
|
|
AD1CON3bits.SAMC = 30; //Used in automatic sampling mode (scan mode). Shall be augmented if results are not accurate. See datasheet.
|
|
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------
|
|
int ADCEnterHallACQMode(void)
|
|
{
|
|
//configure ADC module
|
|
AD1CON1bits.ON = 0; //stop ADC to reconfigure.
|
|
IEC1bits.AD1IE = 0; //disable ADC interrupt for now
|
|
|
|
AD1CHS = 0; //Reset channel source since input source is controlled by hardware in scan mode.
|
|
AD1CON2 = 0;
|
|
AD1CSSL = 0;
|
|
|
|
AD1CON1bits.SSRC = 0b111; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
|
|
// AD1CON1bits.SSRC = 0b000; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
|
|
AD1CON1bits.CLRASAM = 1;
|
|
AD1CON1bits.ASAM = 1;
|
|
|
|
//configure scan mode
|
|
AD1CON2bits.CSCNA = 1; //enable scan mode
|
|
AD1CON2bits.SMPI = 2; //Generate interrupt after the 3rd conversion.
|
|
|
|
AD1CSSLbits.CSSL11= 1; //select Phase A input in scan sequence
|
|
AD1CSSLbits.CSSL12= 1; //select Phase B input in scan sequence
|
|
AD1CSSLbits.CSSL13= 1; //select Phase C input in scan sequence
|
|
AD1CON1bits.SAMP = 1 ;
|
|
|
|
|
|
IPC6bits.AD1IP = 5;
|
|
IPC6bits.AD1IS = 3;
|
|
IFS1bits.AD1IF = 0;
|
|
IEC1bits.AD1IE = 1; //enable ADC interrupt
|
|
|
|
AD1CON1bits.ON = 1; //enable ADC.
|
|
|
|
guiADCMode = ADC_HALL_ACQ_MODE;
|
|
|
|
|
|
return 1;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------
|
|
int ADCEnterTracesMode(void)
|
|
{
|
|
//trick to reuse code but force the good mode :)
|
|
ADCEnterHallACQMode();
|
|
guiADCMode = ADC_TRACE_MODE;
|
|
return 1;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
int ADCEnterCBITMode(void)
|
|
{
|
|
//configure ADC module
|
|
AD1CON1bits.ON = 0; //stop ADC to reconfigure.
|
|
IEC1bits.AD1IE = 0; //disable ADC interrupt for now
|
|
|
|
AD1CHS = 0; //Reset channel source since input source is controlled by hardware in scan mode.
|
|
AD1CON2 = 0;
|
|
AD1CSSL = 0;
|
|
|
|
AD1CON1bits.SSRC = 0b111; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
|
|
// AD1CON1bits.SSRC = 0b000; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
|
|
AD1CON1bits.CLRASAM = 1;
|
|
AD1CON1bits.ASAM = 1;
|
|
|
|
//configure scan mode
|
|
AD1CON2bits.CSCNA = 1; //enable scan mode
|
|
AD1CON2bits.SMPI = 4; //Generate interrupt after the 5th conversion.
|
|
|
|
AD1CSSLbits.CSSL3= 1; //select Vref input in scan sequence
|
|
AD1CSSLbits.CSSL4= 1; //select 5V input in scan sequence
|
|
AD1CSSLbits.CSSL5= 1; //select 3.3V input in scan sequence
|
|
AD1CSSLbits.CSSL8= 1; //select Motor Thermistor input in scan sequence
|
|
AD1CSSLbits.CSSL9= 1; //select Drive Thermistor input in scan sequence
|
|
AD1CON1bits.SAMP = 1;
|
|
|
|
|
|
IPC6bits.AD1IP = 5;
|
|
IPC6bits.AD1IS = 3;
|
|
IFS1bits.AD1IF = 0;
|
|
IEC1bits.AD1IE = 1; //enable ADC interrupt
|
|
|
|
AD1CON1bits.ON = 1; //enable ADC.
|
|
|
|
guiADCMode = ADC_CBIT_MODE;
|
|
|
|
|
|
return 1;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Starts acquistion and conversion of the 3 phases. The 3 inputs are scanned
|
|
// automatically by hardware and an interrupt is triggered when finished.
|
|
//
|
|
int ADCStartHallACQConversion(void)
|
|
{
|
|
AD1CON1bits.ASAM = 1;
|
|
AD1CON1bits.SAMP = 1; //start sampling and start conversion. Interrupt will be generated when data is ready
|
|
return 1;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------
|
|
int ADCStartTracesConversion(void)
|
|
{
|
|
AD1CON1bits.ASAM = 1;
|
|
AD1CON1bits.SAMP = 1; //start sampling and start conversion. Interrupt will be generated when data is ready
|
|
return 1;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
int ADCStartCBITConversion(void)
|
|
{
|
|
if(guiADCMode == ADC_CBIT_MODE)
|
|
{
|
|
AD1CON1bits.ASAM = 1;
|
|
AD1CON1bits.SAMP = 1; //start sampling and start conversion. Interrupt will be generated when data is ready
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
int ADCStopConversion(void)
|
|
{
|
|
return 1;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
|
|
int ADCGetMode(void)
|
|
{
|
|
return guiADCMode;
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
void __ISR(_ADC_VECTOR, ipl5) ADCInterrupt(void)
|
|
{
|
|
switch(guiADCMode)
|
|
{
|
|
case ADC_NORMAL_MODE:
|
|
{
|
|
break;
|
|
}
|
|
case ADC_CBIT_MODE:
|
|
{
|
|
estPAStatus.gusVoltageVref = ADC1BUF0;
|
|
estPAStatus.gusVoltage5V = ADC1BUF1;
|
|
estPAStatus.gusVoltage33V = ADC1BUF2;
|
|
estPAStatus.gusVoltageThermMot = ADC1BUF3;
|
|
estPAStatus.gusVoltageThermDrv = ADC1BUF4;
|
|
|
|
estPAStatus.IsDataReady = 1;
|
|
break;
|
|
}
|
|
case ADC_TRACE_MODE:
|
|
{
|
|
egADCMotPhaseA = ADC1BUF0;
|
|
egADCMotPhaseB = ADC1BUF1;
|
|
egADCMotPhaseC = ADC1BUF2;
|
|
break;
|
|
}
|
|
case ADC_HALL_ACQ_MODE:
|
|
{
|
|
//Update data structure.
|
|
if(gpstHallAcqDataPtr != 0 && gpstHallAcqDataPtr <= gpstHallAcqDataPtrEND)
|
|
{
|
|
gpstHallAcqDataPtr->MotPhaseA = ADC1BUF0;
|
|
gpstHallAcqDataPtr->MotPhaseB = ADC1BUF1;
|
|
gpstHallAcqDataPtr->MotPhaseC = ADC1BUF2;
|
|
gpstHallAcqDataPtr->AnalogDataUpToDate = 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
IFS1bits.AD1IF = 0;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
|
|
//EOF
|
|
|