Show Posts
Pages: 1 2 [3] 4 5 ... 10
31  Products / Arduino Due / Re: Reading analog channel MANUALLY on: December 10, 2013, 12:15:04 pm
-snip-

-Chris

We have been sitting with it for AT LEAST 10 hours trying to solve it, we asked the mentor 3 times already and there is no one else to ask because we're basically ahead of everyone else. What we received as information to what we are supposed to do in order to read the value is to:
Code:
Select/Enable channel with the ADC_CHER registry
Set the ADC clock to 14 MHZ with the ADC_MR registry
Start a conversion with the ADC_CR registry
Wait until ADC_SR's DRDY bit is 1
Read the converted data with either the ADC_LCDR or the ADC_CDRx register

We've tried a lot of different ways to approach this. We have tried setting the values that the adc_init and adc_config functions sets above in the other post, reading the internal temp sensor, turning on freerun mode.... We have tried so many different variations that I can't even remember all of them.

I am not asking anyone to do our school work for us. I am searching for guidance about exactly which registers we need to change in order to make the ADC work. We are not two stupid guys and are capable enough to understand what the different registers do, once we know which ones we need to use.

You can imagine how frustrated we get when all we get from hours of googling is "use AnalogRead".
We only need a small sample of code that is a MUST for using ADC. We obviously need to understand it because we're going to use it for temperature sensors and what not.
This is the adc sampling code I use for my USB Audio Interface. It actually contains everything for reading ADC values.
Code:
#include <Arduino.h>
#include <USB/USBAPI.h>
#include <USB/USBDesc.h>
#include <USB/Audio.h>

boolean B = false;

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_CLOCK1);
  uint32_t rc = VARIANT_MCK/2/frequency; //128 because we selected TIMER_CLOCK4 above
  TC_SetRA(tc, channel, rc/2); //50% high, 50% low
  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 setup() {
  InitAdc();
  AUDIO_InitBuffers(512 * 10);
  while(true)
  {
    if(USBD_GetCurrentInterface() == 1) break;
  }
  udd_enable_endpoint_interrupt(AUDIO_ENDPOINT_DATA & 0xF);
  udd_enable_in_send_interrupt(AUDIO_ENDPOINT_DATA & 0xF);

  startTimer(TC1, 0, TC3_IRQn, 48000);
}

void InitAdc()
{
  adc_init(ADC, 84000000, 84000000/2, 0);
  adc_configure_timing(ADC, 1, ADC_SETTLING_TIME_3, 0);
  adc_disable_all_channel(ADC);
  adc_enable_channel( ADC, (adc_channel_num_t)g_APinDescription[A0].ulADCChannelNumber );
  adc_enable_channel( ADC, (adc_channel_num_t)g_APinDescription[A11].ulADCChannelNumber );
  ADC->ADC_MR &= ~ADC_MR_FWUP;
  ADC->ADC_MR |= ADC_MR_FWUP_OFF;
  ADC->ADC_MR &= ~ADC_MR_LOWRES;
  //ADC->ADC_MR |= ADC_MR_LOWRES_BITS_10;
  ADC->ADC_MR &= ~ADC_MR_FREERUN;
  ADC->ADC_MR |= ADC_MR_FREERUN_ON;
  ADC->ADC_MR &= ~ADC_MR_PRESCAL_Msk;
  ADC->ADC_MR |= ADC_MR_PRESCAL(0);
  ADC->ADC_MR &= ~ADC_MR_SLEEP;
  ADC->ADC_MR |= ADC_MR_SLEEP_NORMAL;
  ADC->ADC_MR &= ~ADC_MR_STARTUP_Msk;
  ADC->ADC_MR |= ADC_MR_STARTUP_SUT0;
  ADC->ADC_MR &= ~ADC_MR_ANACH;
}

void loop() {
 
}

void TC3_Handler()
{
  TC_GetStatus(TC1, 0);

  int data1 = *((uint32_t*)0x400C006C);
  int data2 = *((uint32_t*)0x400C0084);
  //12288 is for centering. Math: (32767 / 2 + 32767 / 4) / 2
  short val1 = map(data1, 0, 4095, -32767, 32767) + 12288;
  short val2 = map(data2, 0, 4095, -32767, 32767) + 12288;

  AUDIO_WriteSample((uint16_t)val1, (uint16_t)val2);
}
I didn't edit anything. If you want a more clean example, just ask.
32  Products / Arduino Due / Re: Reading analog channel MANUALLY on: December 10, 2013, 01:48:45 am
PDC stands for Peripheral DMA Controller. You can find it in the datasheet just like adc stuff: http://www.atmel.com/images/doc11057.pdf
As for reading. Reading ADC_CDR5 should do it. I have done it as well.
33  Products / Arduino Due / Re: Reading analog channel MANUALLY on: December 09, 2013, 12:52:51 pm
As I said, we don't have access to those libraries. I.e. no adc_init and the other.

I would appreciate if you could copy the implementations of those 2 functions.
However, you say "like this" so I  assume that you are only guessing.
I am not guessing as I am using it myself, but I am not sure of that kind of things are actually initialize by default. Anyway, here are the functions.
adc_init:
Code:
/**
 * \brief Initialize the given ADC with the specified ADC clock and startup time.
 *
 * \param p_adc Pointer to an ADC instance.
 * \param ul_mck Main clock of the device (value in Hz).
 * \param ul_adc_clock Analog-to-Digital conversion clock (value in Hz).
 * \param uc_startup ADC start up time. Please refer to the product datasheet
 * for details.
 *
 * \return 0 on success.
 */
uint32_t adc_init(Adc *p_adc, const uint32_t ul_mck,
const uint32_t ul_adc_clock, const uint8_t uc_startup)
{
uint32_t ul_prescal;

/*  Reset the controller. */
p_adc->ADC_CR = ADC_CR_SWRST;

/* Reset Mode Register. */
p_adc->ADC_MR = 0;

/* Reset PDC transfer. */
p_adc->ADC_PTCR = (ADC_PTCR_RXTDIS | ADC_PTCR_TXTDIS);
p_adc->ADC_RCR = 0;
p_adc->ADC_RNCR = 0;

ul_prescal = ul_mck / (2 * ul_adc_clock) - 1;
p_adc->ADC_MR |= ADC_MR_PRESCAL(ul_prescal) |
((uc_startup << ADC_MR_STARTUP_Pos) &
ADC_MR_STARTUP_Msk);
return 0;
}
And adc_configure_timing:
Code:
/**
 * \brief Configure ADC timing.
 *
 * \param p_adc Pointer to an ADC instance.
 * \param uc_tracking ADC tracking time = uc_tracking / ADC clock.
 * \param uc_settling Analog settling time = (uc_settling + 1) / ADC clock.
 * \param uc_transfer Data transfer time = (uc_transfer * 2 + 3) / ADC clock.
 */
void adc_configure_timing(Adc *p_adc, const uint8_t uc_tracking,
const enum adc_settling_time_t settling,const uint8_t uc_transfer)
{
p_adc->ADC_MR |= ADC_MR_TRANSFER(uc_transfer)
| settling | ADC_MR_TRACKTIM(uc_tracking);
}
34  Products / Arduino Due / Re: Reading analog channel MANUALLY on: December 09, 2013, 09:44:03 am
You first need to setup something like this:
Code:
adc_init(ADC, 84000000, 84000000/2, 0);
adc_configure_timing(ADC, 1, ADC_SETTLING_TIME_3, 0);
35  Products / Arduino Due / Re: USB Audio Interface on: December 08, 2013, 08:52:13 am
I got it all working now. It can stream Stereo 48000 Hz 16 (actually 12) bit audio from the arduino's ADC.
36  Products / Arduino Due / Re: binary form in Serial window on: December 05, 2013, 12:41:28 pm
Use BIN instead of HEX.
37  Products / Arduino Due / Re: USB Audio Interface on: December 04, 2013, 01:53:05 pm
The audio interface now fully works correctly (when hid and cdc are disabled). But I need to solve the synchronization problem between the adc and the usb interface.
38  Products / Arduino Due / Re: Additional USB Interfaces on: December 03, 2013, 02:15:35 pm
Okay, the enumeration works now correctly if I disable cdc and hid. (There were some little things that eere wrong)
But now I have the problem that the arduino does not correctly handle the SELECT_INTERFACE command.
39  Products / Arduino Due / Re: Arduino Due blink example in assembly on: December 03, 2013, 01:05:30 am
Quote
a subject that really needs a lot of time.
Yep, you would need a real good reason to do it.

Once upon a time assembly is all we had and you do get to the point where you have so many libraries etc that you can write code pretty fast. These days most of us have got a life and use C (if you can call that getting a life smiley)

_____
Rob
But assembly is sometimes just more efficient. And for exact timing purposes.
40  Products / Arduino Due / Re: Arduino Due blink example in assembly on: December 02, 2013, 01:44:48 pm
I found this in another part of the forum, the only thing that isn't really clear is the masking process do I really need to do that
or using an inline assembly code would be the same?



Code:

/*
    Raw blink sketch for DUE revealing SAM3X8E registers used
    Turns on an LED on for one second, then off for one second, repeatedly.
 */

// Pin 13 mask
uint32_t led = (1u << 27);

void setup()
{                 
  // Output Enable Register
  REG_PIOB_OER = led;
}

// the loop routine runs over and over again forever:
void loop()
{
    REG_PIOB_SODR = led; // Set Output Data Register, turns LED on
    delay(1000);         // wait for a second   
    REG_PIOB_CODR = led; // Clear Output Data Register, turns LED off
    delay(1000);         // wait for a second   
}
Something like this:
Code:
void setup()
{
    asm volatile("mov r0, %[val]"::[val] "r" (&REG_PIOB_OER));
    asm volatile("mov r1, #1, lsl #27");
    asm volatile("str r1, [r0]");
}

void loop()
{
    asm volatile("mov r0, %[val]"::[val] "r" (&REG_PIOB_SODR));
    asm volatile("mov r1, #1, lsl #27");
    asm volatile("str r1, [r0]");
    asm volatile("ldr r0,=1000");
    asm volatile("bl delay");
    asm volatile("mov r0, %[val]"::[val] "r" (&REG_PIOB_CODR));
    asm volatile("mov r1, #1, lsl #27");
    asm volatile("str r1, [r0]");
    asm volatile("ldr r0,=1000");
    asm volatile("bl delay");
}
41  Products / Arduino Due / USB Audio Interface on: December 02, 2013, 01:26:13 pm
I have been working on adding an usb audio interface to the arduino due. So far I got the descriptors working, but when I enable it, the computer doesn't load the driver anymore. When I disable it, it works again. Do I need to modify the driver or something? (The audio interface should work next to the hid and cdc interface)
42  Products / Arduino Due / Re: A/D sampling frequency on: November 30, 2013, 05:19:06 am
How can I reach 100Ksps if the AnalogRead() takes 39us? ...
Use native code. Take a look over here: http://asf.atmel.com/docs/latest/sam3x/html/group__sam__drivers__adc__group.html
43  Products / Arduino Due / Re: A/D sampling frequency on: November 28, 2013, 03:58:01 pm
Ok, then the maximum sampling rate is 1 MHz?
Yes, but only under perfect conditions.
44  Products / Arduino Due / Re: Arduino Due blink example in assembly on: November 28, 2013, 03:33:44 pm
I've found this example but as i found out it's for arduino uno I've managed to find the addresses for the Due but it still doesn't work. Any help would be much appreciated .


Code:
void setup() {
  asm volatile (
    "sbi %0, %1 \n\t"           //pinMode(13, OUTPUT);
    :: "I" (_SFR_IO_ADDR(DDRB)), "I" (DDB5)
  );
}
 
void loop() {
  asm volatile (
     "sbi %0, %1 \n\t"          //LED on
     "call OneSecondDelay \n\t" //delay
     "cbi %0, %1 \n\t"          //LED off
     "call OneSecondDelay \n\t" //delay
     "rjmp 4f \n\t"             //exit
 
  "OneSecondDelay: \n\t"
     "ldi r18, 0 \n\t"          //delay 1 second
     "ldi r20, 0 \n\t"
     "ldi r21, 0 \n\t"
 
  "1: ldi r24, lo8(400) \n\t"
     "ldi r25, hi8(400) \n\t"
  "2: sbiw r24, 1 \n\t"         //10x around this loop = 1ms
     "brne 2b \n\t"
     "inc r18 \n\t"
     "cpi r18, 10 \n\t"
     "brne 1b \n\t"
 
     "subi r20, 0xff \n\t"      //1000 x 1ms = 1 second
     "sbci r21, 0xff \n\t"
     "ldi r24, hi8(1000) \n\t"
     "cpi r20, lo8(1000) \n\t"
     "cpc r21, r24 \n\t"
     "breq 3f \n\t"
 
     "ldi r18, 0 \n\t"
     "rjmp 1b \n\t"
 
  "3: \n\t"
     "ret \n\t"
 
  "4: \n\t"                     //exit
 
     :: "I" (_SFR_IO_ADDR(PORTB)), "I" (PORTB5)
     : "r18", "r20", "r21", "r24", "r25"
  );
}
This is avr assembly. You need arm assembly. As for the registers, yes, it's irritating that it lacks a lot of documentation.
45  Products / Arduino Due / Re: Arduino Due blink example in assembly on: November 28, 2013, 02:07:40 am
Quote
I've searched the web but there isn't much on the subject.
I'm not surprised, no-one in their right mind would use assembly these days unless there is a VERY good reason.

To start from scratch with no C would be a nightmare, but to use inline ASM in your C sketch would be ok so search for examples of inline assembly, get the SAM instruction set docs and start experimenting using some other code as a base.

Good luck, is there a particular reason you want to know the ARM at this level? Very few people need that knowledge.

______
Rob
ARM is not very complex. But it would be much easier if you could use real .s files instead of inline assembly.
Pages: 1 2 [3] 4 5 ... 10