2 Commits

Author SHA1 Message Date
Andrew Gillham
cebcba7d6c Fix ATmega168 comment. 2011-11-04 18:31:11 -07:00
Andrew Gillham
5734af2468 Fix check for ATmega328
The define is __AVR_ATmega328P__ (note the 'P')
2011-11-04 18:26:17 -07:00
3 changed files with 90 additions and 217 deletions

5
README
View File

@@ -48,8 +48,5 @@ below 1MHz. 1MHz works for a basic busy wait trigger that doesn't store
until after the trigger fires.
Please try it out and report back.
This master branch now supports Arduino 1.0 only.
Checkout branch logic_analyzer_v0_5 for Arduino 22 support.
Release: v0.06 November 4, 2011.
Release: v0.05 November 4, 2011.

View File

@@ -78,7 +78,7 @@
* until after the trigger fires.
* Please try it out and report back.
*
* Release: v0.06 November 4, 2011.
* Release: v0.05 November 4, 2011.
*
*/
@@ -102,31 +102,20 @@ void debugdump(void);
* Uncomment CHAN5 to use it as an additional input on a normal Arduino.
* You'll need to change the number of channels in the device profile as well.
*
* Uncomment MEGARAM if you have an Arduino Mega with an external SRAM board with
* at least 64KB on it.
*
* Arduino device profile: ols.profile-agla.cfg
* Arduino Mega device profile: ols.profile-aglam.cfg
* Arduino Mega RAM device profile: ols.profile-aglamr.cfg
*/
#define MEGARAM 1
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define DEBUGPORT PORTH
#define DEBUGDDR DDRH
#define CHANPIN PINF
#define CHAN0 A0
#define CHAN1 A1
#define CHAN2 A2
#define CHAN3 A3
#define CHAN4 A4
#define CHAN5 A5
#define CHAN6 A6
#define CHAN7 A7
#define CHANPIN PINA
#define CHAN0 22
#define CHAN1 23
#define CHAN2 24
#define CHAN3 25
#define CHAN4 26
#define CHAN5 27
#define CHAN6 28
#define CHAN7 29
#else
#define DEBUGPORT PORTD
#define DEBUGDDR DDRD
#define CHANPIN PINB
#define CHAN0 8
#define CHAN1 9
@@ -158,20 +147,11 @@ void debugdump(void);
#define SUMP_SELF_TEST 0x03
#define SUMP_GET_METADATA 0x04
/*
* Default capture buffer sizes. Lower values should work, but the metadata and/or
* device profiles will need to be adjusted to match.
* ATmega168: 532
* ATmega328: 1024 (1KB)
* ATmega2560: 7168 (7KB)
* ATmega2560+external SRAM: 56320 (55KB)
/* ATmega168: 532 (or lower)
* ATmega328: 1024 (or lower)
* ATmega2560: 7168 (or lower)
*/
#if defined(MEGARAM)
#define DEBUG_CAPTURE_SIZE 56320
#define CAPTURE_SIZE 56320
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define DEBUG_CAPTURE_SIZE 7168
#define CAPTURE_SIZE 7168
#elif defined(__AVR_ATmega328P__)
@@ -201,20 +181,7 @@ byte savebytes[128];
int savecount = 0;
#endif /* DEBUG */
/*
* External SRAM adds 56,320 (55kb) directly addressable bytes starting at 0x2200.
* We access it via a hard coded pointer instead of a directly allocated array like
* on other Arduinos.
*
* We only use bank 0 as our capture routines can't spare the cycles to switch banks.
*
*/
#ifdef MEGARAM
byte *logicdata = (byte *) 0x2200U;
#else
byte logicdata[MAX_CAPTURE_SIZE];
#endif
unsigned int logicIndex = 0;
unsigned int triggerIndex = 0;
unsigned int readCount = MAX_CAPTURE_SIZE;
@@ -227,17 +194,6 @@ unsigned long divider = 0;
void setup()
{
#ifdef MEGARAM
XMCRA = _BV(SRE); // Enable external memory interface
pinMode(38, OUTPUT); digitalWrite(38, LOW); // Enable RAM device
pinMode(42, OUTPUT); // Make the bank selection bits output pins
pinMode(43, OUTPUT); // Make the bank selection bits output pins
pinMode(44, OUTPUT); // Make the bank selection bits output pins
digitalWrite(42, LOW); // Select bank 0 (see below for discussion)
digitalWrite(43, LOW); // Select bank 0 (see below for discussion)
digitalWrite(44, LOW); // Select bank 0 (see below for discussion)
#endif // MEGARAM
Serial.begin(115200);
/*
@@ -246,7 +202,7 @@ void setup()
* the sample time. this is used during development to
* properly pad out the sampling routines.
*/
DEBUGDDR = DEBUGDDR | B10000000; /* debug measurement pin */
DDRD = DDRD | B10000000; /* debug measurement pin */
pinMode(CHAN0, INPUT);
pinMode(CHAN1, INPUT);
@@ -269,7 +225,7 @@ void setup()
void loop()
{
unsigned int i;
int i;
if (Serial.available() > 0) {
cmdByte = Serial.read();
@@ -283,10 +239,10 @@ void loop()
break;
case SUMP_QUERY:
/* return the expected bytes. */
Serial.write('1');
Serial.write('A');
Serial.write('L');
Serial.write('S');
Serial.print('1', BYTE);
Serial.print('A', BYTE);
Serial.print('L', BYTE);
Serial.print('S', BYTE);
break;
case SUMP_ARM:
/*
@@ -412,12 +368,6 @@ void loop()
*/
debugdump();
break;
case '3':
/*
* This samples the channel pin and writes to the serial port. Used for debugging.
*/
Serial.print(CHANPIN, HEX);
break;
#endif /* DEBUG */
default:
/* ignore any unrecognized bytes. */
@@ -475,7 +425,7 @@ void getCmd() {
*/
void captureMicro() {
unsigned int i;
int i;
/*
* basic trigger, wait until all trigger conditions are met on port B.
@@ -499,14 +449,14 @@ void captureMicro() {
* any timing unexpectedly.
* Arduino pin 7 is being used here.
*/
DEBUGDDR = DEBUGDDR | B10000000;
DEBUGPORT = B10000000;
DDRD = DDRD | B10000000;
PORTD = B10000000;
delayMicroseconds(20);
DEBUGPORT = B00000000;
PORTD = B00000000;
delayMicroseconds(20);
DEBUGPORT = B10000000;
PORTD = B10000000;
delayMicroseconds(20);
DEBUGPORT = B00000000;
PORTD = B00000000;
delayMicroseconds(20);
if (delayTime == 1) {
@@ -514,34 +464,30 @@ void captureMicro() {
* 1MHz sample rate = 1 uS delay so we can't use delayMicroseconds
* since our loop takes some time. The delay is padded out by hand.
*/
DEBUGPORT = B10000000; /* debug timing measurement */
PORTD = B10000000; /* debug timing measurement */
for (i = 0 ; i < readCount; i++) {
logicdata[i] = CHANPIN;
#ifndef MEGARAM
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
#endif /* MEGARAM */
}
DEBUGPORT = B00000000; /* debug timing measurement */
PORTD = B00000000; /* debug timing measurement */
}
else if (delayTime == 2) {
/*
* 500KHz sample rate = 2 uS delay, still pretty fast so we pad this
* one by hand too.
*/
DEBUGPORT = B10000000; /* debug timing measurement */
PORTD = B10000000; /* debug timing measurement */
for (i = 0 ; i < readCount; i++) {
logicdata[i] = CHANPIN;
#ifndef MEGARAM
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
#endif /* MEGARAM */
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
}
DEBUGPORT = B00000000; /* debug timing measurement */
PORTD = B00000000; /* debug timing measurement */
}
else {
/*
@@ -550,15 +496,13 @@ void captureMicro() {
* a better logic analyzer)
* start of real measurement
*/
DEBUGPORT = B10000000; /* debug timing measurement */
PORTD = B10000000; /* debug timing measurement */
for (i = 0 ; i < readCount; i++) {
logicdata[i] = CHANPIN;
delayMicroseconds(delayTime - 1);
#ifndef MEGARAM
__asm__("nop\n\t""nop\n\t");
#endif /* MEGARAM */
}
DEBUGPORT = B00000000; /* debug timing measurement */
PORTD = B00000000; /* debug timing measurement */
}
/* re-enable interrupts now that we're done sampling. */
@@ -569,7 +513,7 @@ void captureMicro() {
* is done for any triggers, this is effectively the 0/100 buffer split.
*/
for (i = 0 ; i < readCount; i++) {
Serial.write(logicdata[i]);
Serial.print(logicdata[i], BYTE);
}
}
@@ -591,7 +535,7 @@ void captureMicro() {
* this basic functionality.
*/
void captureMilli() {
unsigned int i;
int i;
/*
* very basic trigger, just like in captureMicros() above.
@@ -605,7 +549,7 @@ void captureMilli() {
delay(delayTime);
}
for (i = 0 ; i < readCount; i++) {
Serial.write(logicdata[i]);
Serial.print(logicdata[i], BYTE);
}
}
@@ -618,7 +562,7 @@ void captureMilli() {
*
*/
void triggerMicro() {
unsigned int i = 0;
int i = 0;
logicIndex = 0;
triggerIndex = 0;
@@ -637,14 +581,14 @@ void triggerMicro() {
* any timing unexpectedly.
* Arduino pin 7 is being used here.
*/
DEBUGDDR = DEBUGDDR | B10000000;
DEBUGPORT = B10000000;
DDRD = DDRD | B10000000;
PORTD = B10000000;
delayMicroseconds(20);
DEBUGPORT = B00000000;
PORTD = B00000000;
delayMicroseconds(20);
DEBUGPORT = B10000000;
PORTD = B10000000;
delayMicroseconds(20);
DEBUGPORT = B00000000;
PORTD = B00000000;
delayMicroseconds(20);
if (delayTime == 1) {
@@ -669,9 +613,9 @@ void triggerMicro() {
* we always start capturing at the start of the buffer
* and use it as a circular buffer
*/
DEBUGPORT = B10000000; /* debug timing measurement */
PORTD = B10000000; /* debug timing measurement */
while ((trigger_values ^ (logicdata[logicIndex] = CHANPIN)) & trigger) {
/* DEBUGPORT = B00000000; */
/* PORTD = B00000000; */
/* increment index. */
logicIndex++;
if (logicIndex >= readCount) {
@@ -682,16 +626,12 @@ void triggerMicro() {
* without pin toggles, will try 1 nop.
* __asm__("nop\n\t""nop\n\t""nop\n\t");
*/
#ifndef MEGARAM
__asm__("nop\n\t");
#endif /* MEGARAM */
/* DEBUGPORT = B10000000; */
/* PORTD = B10000000; */
}
/* this pads the immediate trigger case to 2.0 uS, just as an example. */
#ifndef MEGARAM
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
#endif /* MEGARAM */
DEBUGPORT = B00000000; /* debug timing measurement */
PORTD = B00000000; /* debug timing measurement */
/*
* One sample size delay. ends up being 2 uS combined with assignment
@@ -699,16 +639,14 @@ void triggerMicro() {
* between the trigger point and the subsequent samples.
*/
delayMicroseconds(1);
#ifndef MEGARAM
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
#endif /* MEGARAM */
/* 'logicIndex' now points to trigger sample, keep track of it */
triggerIndex = logicIndex;
/* keep sampling for delayCount after trigger */
DEBUGPORT = B10000000; /* debug timing measurement */
PORTD = B10000000; /* debug timing measurement */
/*
* this is currently taking:
* 1025.5 uS for 512 samples. (512 samples, 0/100 split)
@@ -719,13 +657,11 @@ void triggerMicro() {
logicIndex = 0;
}
logicdata[logicIndex++] = CHANPIN;
#ifndef MEGARAM
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
#endif /* MEGARAM */
}
DEBUGPORT = B00000000; /* debug timing measurement */
PORTD = B00000000; /* debug timing measurement */
delayMicroseconds(100);
}
else {
@@ -738,17 +674,17 @@ void triggerMicro() {
* and use it as a circular buffer
*
*/
DEBUGPORT = B10000000; /* debug timing measurement */
PORTD = B10000000; /* debug timing measurement */
while ((trigger_values ^ (logicdata[logicIndex] = CHANPIN)) & trigger) {
/* DEBUGPORT = B00000000; */
/* PORTD = B00000000; */
/* increment index. */
logicIndex++;
if (logicIndex >= readCount) {
logicIndex = 0;
}
/* DEBUGPORT = B10000000; */
/* PORTD = B10000000; */
}
DEBUGPORT = B00000000; /* debug timing measurement */
PORTD = B00000000; /* debug timing measurement */
/* 'logicIndex' now points to trigger sample, keep track of it */
triggerIndex = logicIndex;
@@ -760,20 +696,18 @@ void triggerMicro() {
delayMicroseconds(delayTime);
/* keep sampling for delayCount after trigger */
DEBUGPORT = B10000000; /* debug timing measurement */
PORTD = B10000000; /* debug timing measurement */
for (i = 0 ; i < delayCount; i++) {
if (logicIndex >= readCount) {
logicIndex = 0;
}
logicdata[logicIndex++] = CHANPIN;
delayMicroseconds(delayTime - 3);
#ifndef MEGARAM
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
#endif /* MEGARAM */
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
__asm__("nop\n\t""nop\n\t""nop\n\t");
}
DEBUGPORT = B00000000; /* debug timing measurement */
PORTD = B00000000; /* debug timing measurement */
delayMicroseconds(100);
}
@@ -794,7 +728,7 @@ void triggerMicro() {
if (logicIndex >= readCount) {
logicIndex = 0;
}
Serial.write(logicdata[logicIndex++]);
Serial.print(logicdata[logicIndex++], BYTE);
}
}
@@ -830,68 +764,61 @@ void setupDelay() {
*/
void get_metadata() {
/* device name */
Serial.write((uint8_t)0x01);
Serial.write('A');
Serial.write('G');
Serial.write('L');
Serial.write('A');
Serial.print(0x01, BYTE);
Serial.print('A', BYTE);
Serial.print('G', BYTE);
Serial.print('L', BYTE);
Serial.print('A', BYTE);
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
Serial.write('M');
Serial.print('M', BYTE);
#endif /* Mega */
#if defined(MEGARAM)
Serial.write('R');
#endif /* MEGARAM */
Serial.write('v');
Serial.write('0');
Serial.write((uint8_t)0x00);
Serial.print('v', BYTE);
Serial.print('0', BYTE);
Serial.print(0x00, BYTE);
/* sample memory */
Serial.write((uint8_t)0x21);
Serial.write((uint8_t)0x00);
Serial.write((uint8_t)0x00);
#if defined(MEGARAM)
/* 56320 bytes (55KB) */
Serial.write((uint8_t)0xDC);
Serial.write((uint8_t)0x00);
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
/* 7168 bytes (7KB) */
Serial.write((uint8_t)0x1C);
Serial.write((uint8_t)0x00);
Serial.print(0x21, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
/* 7168 bytes */
Serial.print(0x1C, BYTE);
Serial.print(0x00, BYTE);
#elif defined(__AVR_ATmega328P__)
/* 1024 bytes (1KB) */
Serial.write((uint8_t)0x04);
Serial.write((uint8_t)0x00);
/* 1024 bytes */
Serial.print(0x04, BYTE);
Serial.print(0x00, BYTE);
#else
/* 532 bytes */
Serial.write((uint8_t)0x02);
Serial.write((uint8_t)0x14);
Serial.print(0x02, BYTE);
Serial.print(0x14, BYTE);
#endif /* Mega */
/* sample rate (1MHz) */
Serial.write((uint8_t)0x23);
Serial.write((uint8_t)0x00);
Serial.write((uint8_t)0x0F);
Serial.write((uint8_t)0x42);
Serial.write((uint8_t)0x40);
Serial.print(0x23, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x0F, BYTE);
Serial.print(0x42, BYTE);
Serial.print(0x40, BYTE);
/* number of probes (5 by default on Arduino, 8 on Mega) */
Serial.write((uint8_t)0x40);
Serial.print(0x40, BYTE);
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
Serial.write((uint8_t)0x08);
Serial.print(0x08, BYTE);
#else
#ifdef CHAN5
Serial.write((uint8_t)0x06);
Serial.print(0x06, BYTE);
#else
Serial.write((uint8_t)0x05);
Serial.print(0x05, BYTE);
#endif /* CHAN5 */
#endif /* Mega */
/* protocol version (2) */
Serial.write((uint8_t)0x41);
Serial.write((uint8_t)0x02);
Serial.print(0x41, BYTE);
Serial.print(0x02, BYTE);
/* end of data */
Serial.write((uint8_t)0x00);
Serial.print(0x00, BYTE);
}
/*
@@ -928,7 +855,7 @@ void debugprint() {
}
else {
Serial.print(savebytes[i], HEX);
Serial.write(' ');
Serial.print(' ', BYTE);
}
}
Serial.println("done...");
@@ -939,7 +866,7 @@ void debugprint() {
* of the sample buffer.
*/
void debugdump() {
unsigned int i;
int i;
int j = 1;
Serial.print("\r\n");

View File

@@ -1,51 +0,0 @@
# Configuration for Arduino MegaRAM Logic Analyzer profile
# The short (single word) type of the device described in this profile
device.type = AGLAMR
# A longer description of the device
device.description = Arduino MegaRAM Logic Analyzer
# The device interface, SERIAL only
device.interface = SERIAL
# The device's native clockspeed, in Hertz.
device.clockspeed = 100000000
# Whether or not double-data-rate is supported by the device (also known as the "demux"-mode).
device.supports_ddr = false
# Supported sample rates in Hertz, separated by comma's
device.samplerates = 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000
# What capture clocks are supported
device.captureclock = INTERNAL
# The supported capture sizes, in bytes
device.capturesizes = 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 56320
# Whether or not the noise filter is supported
device.feature.noisefilter = false
# Whether or not Run-Length encoding is supported
device.feature.rle = false
# Whether or not a testing mode is supported
device.feature.testmode = false
# Whether or not triggers are supported
device.feature.triggers = true
# The number of trigger stages
device.trigger.stages = 1
# Whether or not "complex" triggers are supported
device.trigger.complex = false
# The total number of channels usable for capturing
device.channel.count = 8
# The number of channels groups, together with the channel count determines the channels per group
device.channel.groups = 1
# Whether the capture size is limited by the enabled channel groups
device.capturesize.bound = false
# Which numbering does the device support
device.channel.numberingschemes = DEFAULT
# Is a delay after opening the port and device detection needed? (0 = no delay, >0 = delay in milliseconds)
device.open.portdelay = 1000
# Does the device need a high or low DTR-line to operate correctly? (high = true, low = false)
device.open.portdtr = true
# Which metadata keys correspond to this device profile? Value is a comma-separated list of (double quoted) names...
device.metadata.keys = "AGLAMRv0"
# In which order are samples sent back from the device? true = last sample first, false = first sample first
device.samples.reverseOrder = false
###EOF###