benkrasnow
Member
I take a brand new Teensy 3.6 out of the package, and connect it to the computer with a short USB cable, and attach one of the analog pins and digital ground to a benchtop signal generator (photo). After running the below code for about 1 week, the ADC will be permanently damaged. Power cycling and re-programming do not fix the problem. The damage manifests itself as "missing codes" in the ADC digital output. A smoothly changing waveform will show as a blocky discontinuous mess (see photos). I've killed over a half a dozen T3.6's trying to figure out what was going on, and have also posted to this thread: https://community.nxp.com/t5/Kineti...DC-damage-despite-input-protection/m-p/453411 I was fairly certain that input protection was the problem, but this test with a signal generator seems to prove otherwise. This ADC failure is shared for all pins across adc0. adc1 still appears to work normally. Does anyone have any idea what could cause such a failure?
The code looks weird because it has been extracted from a much larger program. The purpose of sending USB in chunks is to fill 64-byte packets instead of dribbling it out.
The code looks weird because it has been extracted from a much larger program. The purpose of sending USB in chunks is to fill 64-byte packets instead of dribbling it out.
Code:
#include <ADC.h>
#define PIN_IMS_SIG A8 // Analog input
#define TX_BUFFER_LEN 750
static int txB_wptr = 1;
static int txB_rptr = 1;
static byte txBuffer[TX_BUFFER_LEN];
IntervalTimer startIMSScan;
IntervalTimer XferDataUSB;
static int samplecount = 0;
static ADC *adc = new ADC(); // adc object
void setup() {
Serial.begin(9600);
startIMSScan.begin(startIMSISR, 42000); // Scan interval in microseconds
XferDataUSB.begin(XferDataISR, 3000); //Send and receive data via USB every 3ms If data is collected at 2 bytes/16us, buffer needs to be >375 bytes
XferDataUSB.priority(130);
}
void loop() {
delay(10);
}
void addByteToTx(uint8_t inbyte)
{
__disable_irq();
txBuffer[txB_wptr] = inbyte;
txB_wptr = (txB_wptr == TX_BUFFER_LEN) ? 0 : txB_wptr + 1;
__enable_irq();
}
void process_USB_IO(void)
{
while(txB_wptr != txB_rptr)
{
__disable_irq();
Serial.write(txBuffer[txB_rptr]);
txB_rptr = (txB_rptr == TX_BUFFER_LEN) ? 0 : txB_rptr + 1;
__enable_irq();
}
//Process incoming USB data (removed from this test code)
}
void XferDataISR()
{
process_USB_IO();
}
void startIMSISR()
{
addByteToTx(0xFF); //Start of packet
addByteToTx(0xFF);
uint16_t tempint = 0x00;
addByteToTx(tempint >> 8);
addByteToTx(tempint & 0xFF);
tempint = 0x00;
addByteToTx(tempint >> 8);
addByteToTx(tempint & 0xFF);
tempint = 0x00;
addByteToTx(tempint >> 8);
addByteToTx(tempint & 0xFF);
tempint = 0x00;
addByteToTx(tempint >> 8);
addByteToTx(tempint & 0xFF);
tempint = 0x00;
addByteToTx(tempint >> 8);
addByteToTx(tempint & 0xFF);
uint32_t temp32 = 0x00;
addByteToTx(0x00);
addByteToTx((temp32 >> 16) & 0xFF);
addByteToTx((temp32 >> 8) & 0xFF);
addByteToTx(temp32 & 0xFF);
__disable_irq();
// bn_ctrl(BN_OPEN);
adc_start_continuous();
delayMicroseconds(50);
// bn_ctrl(BN_CLOSE);
__enable_irq();
}
void adc_start_continuous(void)
{
samplecount = 0;
adc->adc0->setReference(ADC_REFERENCE::REF_EXT);
adc->adc0->setAveraging(4);
adc->adc0->setResolution(16);
adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED_16BITS); //was MED_SPEED
adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // change the sampling speed
adc->adc0->enableInterrupts(adc0_isr);
NVIC_SET_PRIORITY(IRQ_ADC0, 8);
adc->adc0->startContinuous(PIN_IMS_SIG);
}
void adc0_isr(void) {
int tmpval = (uint16_t) adc->adc0->analogReadContinuous() ;
// tmpval = samplecount*50;
if (tmpval > 0xFFF0)
{
tmpval = 0xFFF0;
}
__disable_irq();
addByteToTx((tmpval >> 8) & 0xFF);
addByteToTx(tmpval & 0xFF);
__enable_irq();
if (samplecount++ > 1498)
{
adc->adc0->stopContinuous();
}
}