8 channel simple oscilloscope for the Due

I post here the code for a 8 channel (A0-A7) simple oscilloscope.
Thanks to the arduino due forum community, and especially to stimmer, PakARD (prescaler suggestion) and more.
It streams the data via native serial.

EDIT: Tested with 8 inputs activated: works fine!

150000 interrupts /sec
/
512
*
8192 bytes = 2392064 bytes per/sec = 2.39 MB/sec

Arduino Due Rocks!

Regards,
John

#define NUM_OF_SCOPES 8
static const uint16_t serial_buffer_size = NUM_OF_SCOPES * 1024;
static char my_num_char[serial_buffer_size]="";

static int32_t my_counter = 0;
static uint16_t my_val[12] = {0};
static const uint8_t my_ports_hex[8] = { 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF };
static bool start_transmission = false;
char ch;

void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {
        pmc_set_writeprotect(false);
        pmc_enable_periph_clk( (uint32_t) irq );
        TC_Configure( tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4 );
        uint32_t rc = VARIANT_MCK / 128 / frequency; 
        TC_SetRA(tc, channel, rc / 2 ); 
        TC_SetRC(tc, channel, rc );
        TC_Start(tc, channel);
        tc->TC_CHANNEL[channel].TC_IER =  TC_IER_CPCS;
        tc->TC_CHANNEL[channel].TC_IDR = ~TC_IER_CPCS;
        NVIC_EnableIRQ(irq);
}
void TC3_Handler(){	
	TC_GetStatus(TC1, 0); 
	if(start_transmission) {
	my_counter++;
	while( ( ADC->ADC_ISR & my_ports_hex[ NUM_OF_SCOPES - 1 ] ) != my_ports_hex[ NUM_OF_SCOPES - 1 ] );
	for (uint8_t i = 0; i < NUM_OF_SCOPES; i++){
			my_val[i] = ADC->ADC_CDR[ 7 - i ]; 
			my_num_char[   ( my_counter + i * 512 ) << 1       ] =   my_val[ i ] & 0xFF;
			my_num_char[ ( ( my_counter + i * 512 ) << 1 ) + 1 ] = ( my_val[ i ] >> 8 ) & 0x0F; }
	if(my_counter >= 511) { SerialUSB.write( my_num_char, NUM_OF_SCOPES * 1024 ); my_counter = 0; } 
	}
}


void setup() {
	pinMode(13, OUTPUT);
	analogReadResolution(12);
	pmc_enable_periph_clk(ID_ADC);
	ADC->ADC_MR |= 0x1280;
	ADC->ADC_CR = 2;
	ADC->ADC_CHER = my_ports_hex[ NUM_OF_SCOPES - 1 ]; 
	SerialUSB.begin(9600);
	while(!SerialUSB); 
	delay(100);
	startTimer(TC1, 0, TC3_IRQn, 150000); //16000 //48000//100000
}

void loop(){
if ( ( SerialUSB.available() > 0) ) { 
			ch = SerialUSB.read();
			if( ch == 'F') start_transmission = true; 
			if( ch == 'G') { start_transmission = false; my_counter = 0; }
		} //Read serial

}

To unpack the data and fill the arrays do something like this in your serial/drawing app:

#define NUMBER_OF_SCOPES 8
#define SERIAL_BUFFER_SIZE 8192
static char szBuffer[SERIAL_BUFFER_SIZE] = {""};
LONG lLastError = ERROR_SUCCESS;
static DWORD dwBytesRead = 0;
static unsigned int index[NUMBER_OF_SCOPES] = {0};
static long my_wave_scope[NUMBER_OF_SCOPES][2048] = {0};  
static float height_divisor = ( 100.0f / ( NUMBER_OF_SCOPES * 2.0f ) );
static bool zero_cross = false;
static int sel_cha = 0;


case CSerialWnd::EEventRecv: { 
	lLastError = serial.Read( szBuffer, SERIAL_BUFFER_SIZE, &dwBytesRead ); 
	if(	dwBytesRead == SERIAL_BUFFER_SIZE ){ 
	for ( unsigned int i = 0; i < dwBytesRead; i+=2 ){ 
	sel_cha = i / 1024;
	audio_temp[sel_cha][ (i-sel_cha*1024) >> 1 ] = ( ( szBuffer[ i ] & 0xFF ) | ( ( szBuffer[ i+1 ] & 0x0F ) << 8 ) ) - 2048;}

	for ( unsigned int i = 0; i < 512; i++ ){ 
	if( i == 511 ) { zero_cross = false; index[0] = 0; } else
	if( ( audio_temp[0][ i ] >= 0 && audio_temp[0][ i + 1 ] < 0 ) && !zero_cross ) zero_cross = true; else
	if( zero_cross ) {	
                        my_wave_scope[0][ index[0]++ ] = audio_temp[0][i];
			my_wave_scope[1][ index[0]   ] = audio_temp[1][i]; 
			my_wave_scope[2][ index[0]   ] = audio_temp[2][i]; 
			my_wave_scope[3][ index[0]   ] = audio_temp[3][i];}
					}
				} //expand as necessary
			break; }

Connect each signal with a voltage divider -> 2 100k resistors.

Due Analog input o ------------VV------------o Uno Digital Pin
| (100k)
Z (100k)
|
o
Ground (Uno Ground)