2022-11-17 20:43:21 -05:00

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