Show Posts
|
|
Pages: [1] 2 3 4
|
|
2
|
Using Arduino / Programming Questions / Re: Trying to point a completion function to a class function
|
on: January 27, 2012, 03:57:41 am
|
|
mromani, The idea is along that line except the change in who is the current client happens at a much lower level.
Class B (ie., peripheral B) is transmitting. An event (eg., external interrupt) requests that class C begin transmission soon. Class C requests service but is denied because SPI is busy. However, C has a completion routine and is therefore entered into the queue. A short time later (measured in tens of microseconds) B's transmission ends. B's completion function is called with the argument "SPI_TRANSFER_DONE". If B has been assembling more data to send and is ready, it will then request service but will be denied because there is at least one other in the queue. However, it will be added to the queue.
Then C's completion code is called with the argument "SPI_NOW_AVAILABLE". The pointer now selects class C, C begins transmission and control returns to whatever was interrupted when B's last byte finished transmitting.
The whole point is to minimize delays between the time peripheral X requests service and when that service is actually available. The other consideration is to minimize the time spent servicing each interrupt so everything has to be ready to roll before a call for service is made.
I'll post again when I have something actually working with multiple peripherals. I have been trying to get a handle on how much time some simple code actually takes and have been getting interesting results. For instance, shifting an integer 15 (i << 15) takes 107 cycles and (i<<j, where j is 15) takes 112; that's 7 microseconds with a 16 MHz clock!
Pete
|
|
|
|
|
3
|
Using Arduino / Programming Questions / Re: Trying to point a completion function to a class function
|
on: January 26, 2012, 04:43:50 pm
|
|
The reason for preferring a class is that there are several SPI peripherals sharing a base class which handles the actual SPI. Also, I am quite familiar with classes.
What I have done that does compile is to add a static function to which the compiler is happy to make a pointer. The static function then references a private global which points to the instance to call the actual completion class function. Now I just have to see if I can get the whole thing to work!
Thanks for your suggestions and comments; they have been helpful.
|
|
|
|
|
5
|
Using Arduino / Programming Questions / Re: Trying to point a completion function to a class function
|
on: January 26, 2012, 02:57:36 pm
|
|
Nick, the global "Aptr" points to the particular instance in operation when the interrupt occurs. In the ISR, the completion function is prefaced by "Aptr->" to specify the current instance.
However, if I cannot solve the problem I am asking about, I will point the completion function variable to a non-class routine that can access a pointer to the instance of B which can then call the real completion function. I just cannot figure why that should be necessary.
In the B constructor, it now knows where the completion function is and should be able to place the pointer for access by the ISR. I just cannot figure out how to coerce the compiler to accept that this is legitimate.
|
|
|
|
|
7
|
Using Arduino / Programming Questions / Trying to point a completion function to a class function
|
on: January 26, 2012, 02:11:56 pm
|
I have a base class operating SPI with interrupt enabled - "A". I have two or more classes ("B", "C", etc.) derived from "A" to operate different peripherals. In the interrupt routine I want to call a completion function. The compiler does not object if the completion function is not a class function but does if it is. The error message seems to indicate that this is a casting problem: "error: argument of type 'void (LCDnokia12:  (uint8_t)' does not match 'void (*)(uint8_t)'" The bares bones of the relevant code is: class A { ... public ... void (*completionFunction)(uint8_t purpose); // Function pointer ... void func1(A *client); // Function in class A ... }
volatile A *Aptr; // Pointer to the current client.
void A::func1(A *client) // Called by client { Aptr = client; }
ISR(SPI_vect) { Aptr->completionFunction(SPI_TRANSFER_DONE); // Use completion function }
class B : A { ... bCompletionFunction(uint8_t status); // Forward declaration of actual completion function ... }
B:B() // B constructor { completionFunction = bComletionFunction; // This is the problem!!! }
void B::someFunction() { func1(this); // Establish this as client. void B::bCompletionFunction(uint8_t status) // Completion function { }
Any suggestions as to how to fix this problem?
|
|
|
|
|
8
|
Using Arduino / Programming Questions / Seeking advice re SPI timing
|
on: January 16, 2012, 08:25:43 am
|
I will be running two to four peripherals via SPI. For some, a speed of 0.5 microseconds per bit (4 microseconds per byte) is feasible, others will run slower. In each case, a transmission will consist of 1 to 16 bytes. For the slow ones (16 or 32 microseconds per byte) I plan to use SPI interrupt. However, for the fast ones, I believe I would get better speed by handling the whole transfer in software using code such as: for (int i=0; i<count; i++) { SPDR = buffer[i]; while (!(SPSR & (1 << SPIF))); buffer[i] = SPDR; }
Is this a reasonable assumption? A RETI instruction takes 4 cycles; does anyone know approximately how long the interrupt takes?
|
|
|
|
|
10
|
Using Arduino / Programming Questions / Don't understand error "... which is of non-class type 'SPIbase ()()'"
|
on: January 15, 2012, 05:36:40 pm
|
I have a problem understanding the error message: SPItest1:11: error: request for member 'begin' in 'spiTest', which is of non-class type 'SPIbase ()()' I am just beginning to write this library routine and wanted to check for errors before I got too far. The sketch is: /*
*/
#include "SPIbase.h"
SPIbase spiTest();
void setup() { Serial.begin(9600); spiTest.begin(6); }
void loop() { bool fr = spiTest.SPIisFree(spiTest); }
The library header file is: #ifndef SPIBASE_H #define SPIBASE_H
#include "Arduino.h"
typedef struct { unsigned char ssPin; unsigned char buffer[11]; } SPIparams_t;
class SPIbase { SPIparams_t SPIparams; public: SPIbase(); void begin(unsigned char pin); bool SPIisFree(SPIbase *client); void SPIsetFree(SPIbase *client); };
#endif
The cpp file is: #include "SPIbase.h" #include <avr/interrupt.h>
volatile SPIbase *basePtr;
SPIbase::SPIbase() { }
void SPIbase::begin(unsigned char pin) { SPIparams.ssPin = pin; }
bool SPIbase::SPIisFree(SPIbase *client) { if (!basePtr) { basePtr = client; return true; } else return basePtr == client; }
void SPIbase::SPIsetFree(SPIbase *client) { if (basePtr == client) basePtr = 0; }
What is wrong?
|
|
|
|
|
13
|
Using Arduino / Project Guidance / Re: SPI vs I2C; which is best?
|
on: November 19, 2011, 06:44:21 pm
|
|
Thank you Mike,
Although your moniker and picture do not inspire as much confidence as John's, I will take your advice into consideration. I rather like the simplicity of SPI and am leaning in that direction.
|
|
|
|
|
14
|
Using Arduino / Project Guidance / Re: SPI vs I2C; which is best?
|
on: November 19, 2011, 06:35:00 pm
|
|
Thank you, John,
Every bit of advice is valuable and will be taken into consideration.
In fact I do need a number of temperature sensors. Do you have part numbers for these? I am usually dealing with Sparkfun and Digi-Key.
|
|
|
|
|
15
|
Using Arduino / Project Guidance / SPI vs I2C; which is best?
|
on: November 19, 2011, 06:03:37 pm
|
|
I want to have the Arduino Uno monitoring a number of different digital sensors that use either I2C or SPI.
With some sensors I am stuck with whatever is available, with other sensors I am offered a choice of using I2C or SPI. The SPI technology appears to be more robust than the I2C. I2C can handle a lot of devices with only two digital pins but there is the overhead of addressing and requirements for acknowledgement plus clocking appears to be more critical. SPI requires four pins plus one additional for each sensor but there is no acknowledgement and the clocking appears to be less critical.
What does experience say? Is it easier to have a number of sensors on I2C or SPI?
Pete
|
|
|
|
|