Show Posts
Pages: [1] 2
1  Products / Arduino Due / Re: Continuous SPI for multiple bytes on: April 02, 2014, 05:02:58 pm
Right, because PORTD is for the Uno/Mega...
Thanks!
2  Products / Arduino Due / Re: Continuous SPI for multiple bytes on: April 02, 2014, 08:22:12 am
Yes, my CS goes low and back high, it's just off the frame. I'm using the CS down slope to trigger my scope.
Here is an updated copy of my code (working) for those in the future who may run into this problem also.

My next step is to remind myself how to do direct port manipulation for the CS LOW/HIGH, as there is a long delay before / after the actual transfer before the CS pin flips.
IIRC should be something like PORTD = PORTD & 0b00100000 ....
Anyhow, I don't need help on that, I can figure it out smiley

Code:
/*
 * SPI Communication via Arduino, version 2.0 using DMA
 * Send via USB Serial
 * Used for programming/Interfacing with LM96570
 *
 * DMASPI obtained from
 * https://github.com/manitou48/DUEZoo/blob/master/dmaspi.ino
 *
 * Author: Michael, 2014
 * mcleung@uwaterloo.ca
 */

// dmaspi   from SdFat lib

#define USE_ARDUINO_SPI_LIBRARY 0
#define  USE_NATIVE_SAM3X_SPI 1

// #include <SPI.h>
#define USE_ARDUINO_SPI_LIBRARY 0
#define USE_NATIVE_SAM3X_SPI 1

#define CS 10
#define SPI_RATE 2 // 84 / SPI_RATE = 42 MHz

// Save Words to write to chip
#define SPI_BUFF_SIZE 9
uint8_t rx_buffer[SPI_BUFF_SIZE]; // Not used
uint8_t tx_buffer[SPI_BUFF_SIZE];

void setup()
{
  // Set up Serial communication (Computer)
  Serial.begin(115200);
  Serial.println("Initialisation Started");
  pinMode(CS,OUTPUT);
  digitalWrite(CS,HIGH);
  spiBegin();
  spiInit(SPI_RATE);
  
  Serial.println("Initialisation Completed");
}


void loop() {
  if (Serial.available()) {
    serialRead();
  }
}

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
*/
void serialRead() {
  Serial.println("    "); // Unknown why it's required
  tx_buffer[0]=Serial.read();
  tx_buffer[1]=Serial.read();
  tx_buffer[2]=Serial.read();
  tx_buffer[3]=Serial.read();
  tx_buffer[4]=Serial.read();
  tx_buffer[5]=Serial.read();
  tx_buffer[6]=Serial.read();
  tx_buffer[7]=Serial.read();
  tx_buffer[8]=Serial.read();
  //Serial.print("READ");
  //Word1 = Serial.parseInt();
  //Serial.print("READSUCESS");
  digitalWrite(CS,LOW);
  spiSend(tx_buffer,SPI_BUFF_SIZE);
  digitalWrite(CS,HIGH);

  // Return 1 so computer knows that Arduino is ready to recieve next command
  delay(1000);
  Serial.print("1");
  //Serial.print("DONE");

  // Clear unsused bytes from the buffer
  // This should only occur from transmission errors
  byte dummy;
  while(Serial.available() > 0) {
    dummy = Serial.read();
  }
}

And then the DMA SPI part, copied word for word, starting from line 37.
I can't post the entire part as I'm over the character limit.
https://github.com/manitou48/DUEZoo/blob/master/dmaspi.ino

Code:
// SPI functions
//==============================================================================
#if USE_ARDUINO_SPI_LIBRARY
#include <SPI.h>
3  Products / Arduino Due / Re: Continuous SPI for multiple bytes on: April 01, 2014, 01:13:29 pm
One line solution did not help.

DMA found at https://github.com/manitou48/DUEZoo/blob/master/dmaspi.ino works perfectly.
I tested at 42MHz (Div by 2)

Still didn't manage to program the chip, but I don't think it's Arduino's fault anymore, probably my wires can't handle the high frequency.
See scope obtained, I transmitted 0xAAAA 0xAAAA ... etc
Channel 1 is the MOSI, at 42 MHz
Channel 2 is the latch enable which is pulled low!

Thanks for your help everyone smiley

4  Products / Arduino Due / Re: Noise in Due DAC on: March 31, 2014, 10:06:19 pm
You won't be able to output 5mV directly. You will probably need to use voltage divider (resistors) to achieve it.
I can't find the source anymore, but the Due's DAC only output from 1/6 to 5/6 of the full (0 to 3.3V) voltage range.

Hence analogWrite(DAC1, 0); would correspond to 0.55V, and it goes up to 2.75V (ish)

Noise will depend on how much current is drawn, as well as EMF and capacitors you use. From my experience this should be a few  millivolts, but it also depends on what you are making your Due compute (timer interupts, etc)
5  Products / Arduino Due / Re: Continuous SPI for multiple bytes on: March 31, 2014, 08:47:21 pm
@dlloyd, I'm not too familiar with low level programming on micro-controllers. I'll try implementing your one line change tomorrow. But from my understanding is that the SPI library coded the delay, and therefore I can remove/override it with DLYBCT = 0.

I also found this DMA SPI on Github. Would I be able to use it? (I'm trying to understand the arrow notation -> )
https://github.com/manitou48/DUEZoo/blob/master/dmaspi.ino

Arduino community is awesome, I get answers much faster here than with TI  smiley
6  Products / Arduino Due / Re: Continuous SPI for multiple bytes on: March 31, 2014, 04:24:39 pm
I'll give this a try and report back to you guys.
I've posted the corresponding question to the TI E2E forums, and I'm awaiting their responses.
http://e2e.ti.com/support/applications/high_reliability/f/30/t/331309.aspx

I would hope that the clock doesn't need to be synchronous (hence why it needs a clock line) but we will see what the TI Engineers say. Hopefully I don't need to port my system to an FPGA to meet the timing requirements, I prefer programming with Arduino smiley

Graynomad:  I know, for now I am transferring a total of 9 bytes, but eventually I want to be able to transfer an arbitrary number of bytes.

Try this line right after SPI.setDataMode ...
Code:
SPI0->SPI_CSR[0] = SPI0->SPI_CSR[0] & 0xFFFFFF; // clear delay between consecutive transfers (DLYBCT = 0)

Note: The default (DLYBCT = 1) keeps CS enabled for 32 MCLK after a completed transfer. Some device needs that for working properly (from spi.cpp).

7  Products / Arduino Due / Continuous SPI for multiple bytes on: March 28, 2014, 04:39:38 pm
As of April 2, 2014, this has been fixed using DMA SPI. See reply #15 for working copy of the code.
DMA SPI obtained from
https://github.com/manitou48/DUEZoo/blob/master/dmaspi.ino



Hi guys,

I'm trying to program a ship that requires 4 wire serial programming (essentially SPI)
For those who are curious, it's the LM96570.

The chip uses up to 80MHz on the serial line.
I've been able to create a simple program for my Due to communicate with the chip.
The issue I'm having is that although the SPICONTINUE works as it is intended to (by leaving the LE low), the data is transmitted in little "burts" of information, one byte (8 bits) at a time, then a long delay before the next byte.
The clock flips as I expect it to, but again, flips 8 times and then there is a long pause.

I am suspecting that it's causing mis-communication problems with my IC chip, and the lowest I've been able to achieve a constant clock is down at 800KHz. I was wondering if any of you had any luck pushing continuous SPI communication to tens of MHz without these long pauses between bytes.

Any suggestions to make my code more efficient is also welcomed.
I am passing the bytes from a python serial script.

Code:
#include <SPI.h>
// Define SPI Pins
// Can only use 4 10 and 52
#define LEPin 10


// Save Words to write to API
// Integer is 4 byte in Due (32 bits)
// Worst Case scenario is need to write 70 bits (5 addr + 0 + 64 data)
unsigned char Word1 = 0xAA;
unsigned char Word2 = 0xFF;
unsigned char Word3 = 0x00;
unsigned char Word4 = 0x00;
unsigned char Word5 = 0x00;
unsigned char Word6 = 0x00;
unsigned char Word7 = 0x00;
unsigned char Word8 = 0x00;
unsigned char Word9 = 0x00;


void setup()
{
  // Set up Serial communication (Computer)
  Serial.begin(115200);
  Serial.println("Initialisation Started");
  
  // Set up SPI communication (Chip)
  SPI.begin(LEPin);
  SPI.setClockDivider(LEPin, 42); // Desired 80 MHz Due is 84, so try div 2
  // 84 should correspond to 1MHz
  SPI.setBitOrder(LEPin, MSBFIRST);
  
  // TODO: SPI Set Data Mode http://arduino.cc/en/Reference/SPISetDataMode
  SPI.setDataMode(LEPin, 0);
  
  Serial.println("Initialisation Completed");
}


void loop() {
  if (Serial.available()) {
    serialRead();
  }
}

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
*/
void serialRead() {
  Serial.println("    "); // Unknown why it's required
  
  //Serial.print("READ");
  Word1 = Serial.read();
  Word2 = Serial.read();
  Word3 = Serial.read();
  Word4 = Serial.read();
  Word5 = Serial.read();
  Word6 = Serial.read();
  Word7 = Serial.read();
  Word8 = Serial.read();
  Word9 = Serial.read();
  //Serial.print("READSUCESS");
  
  SPI.transfer(LEPin, Word1, SPI_CONTINUE);
  SPI.transfer(LEPin, Word2, SPI_CONTINUE);
  SPI.transfer(LEPin, Word3, SPI_CONTINUE);
  SPI.transfer(LEPin, Word4, SPI_CONTINUE);
  SPI.transfer(LEPin, Word5, SPI_CONTINUE);
  SPI.transfer(LEPin, Word6, SPI_CONTINUE);
  SPI.transfer(LEPin, Word7, SPI_CONTINUE);
  SPI.transfer(LEPin, Word8, SPI_CONTINUE);
  SPI.transfer(LEPin, Word9, SPI_LAST);
    
  // Return 1 so computer knows that Arduino is ready to receive next command
  delay(1000);
  Serial.print("1");
  //Serial.print("DONE");
}
8  Using Arduino / Programming Questions / Re: Apply Constant Voltage with Switch on: February 18, 2013, 10:12:41 pm
Define will basically find and search the first "word" and replace it with the second "word"

Thus in your sketch, during compilation it would replace all the instances of "actuator" with "13". For example, it would be digitalWrite(13, HIGH);
There is no point to make "actuator" a variable if it will not change during the entire sketch.

Sorry, you are right, I was missing a digitalRead command first. Mail loop should be:

boolean Ypos = 0;
boolean Yneg = 0;
Code:
void loop()
{
Ypos = digitalRead(YposPin);
Yneg = digitalRead(YnegPin);
  if (Ypos)
  {
    digitalWrite(actuator, HIGH);
  }
  if (Yneg)
  {
    digitalWrite(actuator, LOW);
  }
}
9  Using Arduino / Programming Questions / Re: Need some help with subroutine on: February 18, 2013, 10:01:31 pm
Not sure what your other codes are doing, but if you are using Timers or Interupts that would kill your ability to use millis()
10  Products / Arduino Due / Re: baudrate error on: February 18, 2013, 09:44:33 pm
Hi,

Did you setup your Arduino to receive at 57.6k?  Have you tried to receive the data on your PC, and are the missing characters there?
Do you use timers in your Arduino code?
I've used my Due @115.2k and 57.6k sending 100-200 characters without problem, so it may be because of the longer messages.

Can we see your entire code to try and solve the issue?
11  Using Arduino / Programming Questions / Re: Apply Constant Voltage with Switch on: February 18, 2013, 08:57:33 pm
By "Negative Voltage" I'll assume you mean 0V, as the arduino can not output negative voltage. If that is what you want/require, then you will need to set up an exteral circuit. Also, I'm not sure what the current draw of your servo requires, but again, I will assume that it is within the limits of the Arduino.

You'll need to set up two input pins, one to know when the joystick is +y, and one when it is -y.

From what I can see from your joystick is that they are simple togglebuttons, they will either be opencircuit when pushed or be short circuit when pushed. You will need to experiment to determine which it is.

Also, just a suggestion but you should use #DEFINE for the actuator pin since it doesn't change throughout your sketch.
See http://arduino.cc/en/Reference/Define

One thing with this sketch is that it will stay in the positive/negative state until you tell it to inverse, the arduino is digital (1 or 0) there is no positive, zero and negative voltage available unless you use more then one pin.

Code:
#DEFINE actuator 13
#DEFINE YposPin 10
#DEFINE YnegPin 11

void setup()
{                
  pinMode(actuator, OUTPUT);
  pinMode(YposPin , INPUT);
  pinMode(YposPin , INPUT);
}
void loop()
{
  if (YposPin)
  {
    digitalWrite(actuator, HIGH);
  }
  if (YnegPin)
  {
    digitalWrite(actuator, LOW);
  }
}
12  Products / Arduino Due / Re: Upload terribly slow. on: February 16, 2013, 12:46:36 am
Hi,

I believe that it is the norm. I'm experiencing similar upload times. The new thing about the Due vs the Uno or the Mega is that it needs to "flash" the memory, and writing and verifying the pages seems to be the bottleneck.

I've tried to disable the "verify code after upload" in the preferences however it does not seem to work as code is still verified.
13  Products / Arduino Due / Re: How to you write to the second DAC? on: February 16, 2013, 12:35:24 am
You are using the direct writing to the DAC, which I've noticed to be much faster then using analogWrite.

If you look at your code, you should have "initialized" your DAC earlier with
Code:
analogWrite(DAC1,0);
. Thus all the
Code:
dacc_write_conversion_data(DACC_INTERFACE, value);
will be writing to DAC1. If you change that to
Code:
analogWrite(DAC2,0);
, then you will be writing directly to DAC2. At least that is the case from my experience.

Let me know if it helps!

M
14  Using Arduino / Project Guidance / Re: OP-AMP for SoundAmp in my proyect. on: February 28, 2012, 11:33:37 am
Just make sure the speakers you use are high input impedance, your LM324 can only drive a couple mA.
15  Using Arduino / Project Guidance / Re: Arduino Nano and Voltage Pin on: February 28, 2012, 11:20:55 am
Unless you are drawing large currents on some of the nano output pins, it should be fine.
If you do draw more then what the battery can supply, then you'll notice funny behavior from your arduino. If this occurs, you could try using 2 or more batteries in parallel
Pages: [1] 2