Show Posts
Pages: 1 2 3 [4] 5 6 ... 11
46  Using Arduino / Programming Questions / Re: Using templates in a library (solved(almost)) on: December 03, 2012, 10:35:10 am
In the serial monitor, when I run the sketch, I get

1
20
2
0

I should get

1
20
2
256

If I change the second write from uint16_t to uint8_t type it returns correctly. As I stated earlier templates are very confusing to me, but I almost have this working. Frustrating! smiley-yell I really do apreciate any help on this. The functions in question are the last two in the library. The rest of the library works fine.

Again thanks for your time,
DJ
47  Using Arduino / Programming Questions / Re: Using templates in a library (solved(almost)) on: December 03, 2012, 10:31:25 am
Here's the library:
Code:
#ifndef EXMEM_H
#define EXMEM_H

#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

#include <inttypes.h>
#include <avr/io.h>

class exmem
{
    public:
        exmem();
        void enable(uint8_t addressWidth = 16,
        uint16_t lowerLimit = 0x0000,
        uint8_t upperSectorWaitState = 0x00,
        uint8_t lowerSectorWaitState = 0x00);
        void disable(void);
        template <class TYPE> uint16_t write(bool sector, uint16_t address, const TYPE &data);
        template <class TYPE> uint16_t read(bool sector, uint16_t address, TYPE &store);
};


extern exmem ExMem;

static uint16_t upperSectorOffset = 0x0000;
static uint16_t upperLimit = 0xFFFF;
static uint16_t upperSize = 0xDE00;
static uint16_t lowerSize = 0xDE00;

exmem::exmem()
{
}    

void exmem::enable(uint8_t addressWidth, uint16_t upperSectorBoundry,
                   uint8_t upperSectorWaitState, uint8_t lowerSectorWaitState)
{
    switch (addressWidth)
    {
        XMCRB &= 0xF8;
        case 8:
            upperLimit = 0x00FF;
            XMCRB = 0x07;
            break;
        case 10:
            upperLimit = 0x03FF;
            XMCRB = 0x06;
            break;
        case 11:
            upperLimit = 0x07FF;
            XMCRB = 0x05;
            break;
        case 12:
            upperLimit = 0x0FFF;
            XMCRB = 0x04;
            break;
        case 13:
            upperLimit = 0x1FFF;
            XMCRB = 0x03;
            break;
        case 14:
            upperLimit = 0x3FFF;
            XMCRB = 0x02;
            break;
        case 15:
            upperLimit = 0x7FFF;
            XMCRB = 0x01;
            break;
        default:
            upperLimit = 0xFFFF;
            break;
    }
    uint16_t boundry;
    if (addressWidth < 15)
    {
        boundry = 0x0000;
    }
    else if (addressWidth < 16)
    {
        boundry = constrain(upperSectorBoundry, 0x0000, 0x6000);
    }
    else
    {
        boundry = upperSectorBoundry;
    }
    XMCRA &= 0x8F;
    switch (boundry)
    {
        case 0x4000:
            upperSectorOffset = 0x1E00;
            XMCRA |= 0x20;
            break;
        case 0x6000:
            upperSectorOffset = 0x3E00;
            XMCRA |= 0x30;
            break;
        case 0x8000:
            upperSectorOffset = 0x5E00;
            XMCRA |= 0x40;
            break;
        case 0xA000:
            upperSectorOffset = 0x7E00;
            XMCRA |= 0x50;
            break;
        case 0xC000:
            upperSectorOffset = 0x9E00;
            XMCRA |= 0x60;
            break;
        case 0xE000:
            upperSectorOffset = 0xBE00;
            XMCRA |= 0x70;
            break;
        default:
            upperSectorOffset = 0x0000;
            break;
    }
    if (0 < upperSectorOffset)
    {
        lowerSize = upperSectorOffset;
        upperSize = ((1 + upperLimit) - (0x2200 + upperSectorOffset));
    }
    else
    {
        lowerSize = upperSize = ((1 + upperLimit) - 0x2200);
    }
    switch (upperSectorWaitState)
    {
        XMCRA &= 0xF3;
        case 1:
            XMCRA |= 0x04;
            break;
        case 2:
            XMCRA |= 0x08;
            break;
        case 3:
            XMCRA |= 0x0C;
            break;
        default:
            break;
    }
    switch (lowerSectorWaitState)
    {
        
            XMCRA &= 0xFC;
        case 1:
            XMCRA |= 0x01;
            break;
        case 2:
            XMCRA |= 0x02;
            break;
        case 3:
            XMCRA |= 0x03;
            break;
        default:
            break;
    }
    XMCRA |= 0x80;
}

void exmem::disable(void)
{
    XMCRA &= 0x7F;
}

template <class TYPE>
uint16_t exmem::write(bool sector, uint16_t address, const TYPE &data)
{
    uint8_t *pExtMemory = reinterpret_cast <uint8_t *> (0x2200);
    const uint8_t *pData = (const uint8_t *)(const void *)&data;
    uint16_t i;
    i = 0;
    if (sector)
    {
        if (address >= upperSize)
        {
            return i;
        }
    }
    else
    {
        if (address >= lowerSize)
        {
            return i;
        }
    }
    for (; i < sizeof(data); i++)
    {
        if (sector)
        {
            uint8_t *pMemory;
            pMemory = (uint8_t *)(pExtMemory + upperSectorOffset + address++);
            *pMemory = (uint8_t)(*pData);
        }
        else
        {
            uint8_t *pMemory;
            pMemory = (uint8_t *)(pExtMemory + address++);
            *pMemory = (uint8_t)(*pData);          
        }
    }
    return i;
}

template <class TYPE>
uint16_t exmem::read(bool sector, uint16_t address, TYPE &store)
{
    uint8_t *pExtMemory = reinterpret_cast <uint8_t *> (0x2200);
    uint8_t *pStore = (uint8_t *)(void *)&store;
    uint16_t i;
    i = 0;
    if (sector)
    {
        if (address >= upperSize)
        {
            return i;
        }
    }
    else
    {
        if (address >= lowerSize)
        {
            return i;
        }
    }
    for (; i < sizeof(store); i++)
    {
        if (sector)
        {
            uint8_t *pMemory = (pExtMemory + upperSectorOffset + address++);
            *pStore++ = (TYPE)(*pMemory);
        }
        else
        {
            uint8_t *pMemory = (pExtMemory + address++);
            *pStore++ = (TYPE)(*pMemory);
        }
    }
    return i;
}

exmem ExMem = exmem();

#endif

Can someone please tell me why the second read returns incorrectly.

Thanks for your time,
DJ
48  Using Arduino / Programming Questions / Using templates in a library (SOLVED) on: December 03, 2012, 10:29:30 am
I wrote a library for the External Memory interface module on the mega1280/2560. I wanted to incorperate templates into the library so I can pass any type as an argument to the functions. Someone suggested EEPROMWriteAnything from the Arduino Playground. I used the template parts of it in my library. My library and sketch are below. I really don't understand templates. I just copied that part into my library. I got it to compile and work, almost. In the sketch I write to external memory twice. The first time I pass a uint8_t type (20) to the write function, the second time I pass a uint16_t type (256). Then I read back the data from the same two addresses I had written to. In the case of the uint8_t type the data returns correctly (20). In the case of the uint16_t type it returns incorrectly (0).

Here's the sketch:
Code:
#include <ExMem.h>

void setup()
{
    Serial.begin(115200);
    // Enables the interface with two sectors with the upper/lower boundry at 0x8000 and no wait-states
    ExMem.enable(16, 0x8000, 0, 0);
    uint8_t x1 = 20;
    uint16_t y1 = 256;
    ExMem.write(0, 0x0020, x1); // write to lower sector address 0x0020
    ExMem.write(0, 0x0030, y1); // write to lower sector address 0x0030
    // varibles to hold data read
    uint8_t x2;
    uint16_t y2;
    // The function places the data in the supplied variable
    // and returns the number of bytes read.
    Serial.println(ExMem.read(0, 0x0020, x2), DEC);
    Serial.println(x2, DEC);
    Serial.println(ExMem.read(0, 0x0030, y2), DEC);
    Serial.println(y2, DEC);
}

void loop()
{
}

Sorry, I have to post twice, due to the size of the library.
49  Using Arduino / Programming Questions / Re: how to create original interrupts [ ISR() ] on: November 28, 2012, 05:18:47 am
The avrFreaks tutorial above states:
Quote
There are two main sources of interrupts:

Hardware Interrupts, which occur in response to a changing external event such as a pin going low, or a timer reaching a preset value
 Software Interrupts, which occur in response to a command issued in software

The 8-bit AVRs lack software interrupts, which are usually used for special operating system tasks like switching between user and kernel space, or for handling exceptions.

From the ATmega1280/2560 datasheet:
Quote
The External Interrupts are triggered by the INT7:0 pin or any of the PCINT23..0 pins.
Observe that, if enabled, the interrupts will trigger even if the INT7:0 or PCINT23..0 pins
are configured as outputs. This feature provides a way of generating a software
interrupt.

On the arduino (mega1280/2560, I'm not sure of others), there are pins on the MCU that aren't brought out to headers. Some of those pins also serve as interrupt sources. So, if you set one of those pins to output, you can use software to set the state of the pin and trigger an interrupt to occur (hardware interrupt triggered by software). This can also be done with (external interrupt) pins that are brought out to headers. If anyone else has anything to add/corrections, please do.

DigitalJohnson
50  Using Arduino / Programming Questions / Re: Help using templates. on: November 28, 2012, 04:01:46 am
@WizenedEE
You forgot Serial.begin();
To be honest I have no idea how your example works. smiley-confuse I'm not that good at coding yet. But thanks for it anyway. I'll study it some more and see if I can figure it out.

DJ
51  Using Arduino / Programming Questions / Re: Help using templates. on: November 28, 2012, 01:12:52 am
Thanks Nick, that worked. I didn't know the template was part of the function declaration.

Quote
By the time you get to templates, this should be second nature.

Does this mean I'm in over my head?... You're probably right. smiley-razz

Thanks for the replies,
DJ
52  Using Arduino / Programming Questions / Re: Help using templates. on: November 26, 2012, 08:48:52 am
Nope. Same error: 'TYPE' does not name a type.

My sketch:
Code:
template<class TYPE> TYPE Add(TYPE n1, TYPE n2);

TYPE Add(TYPE n1, TYPE n2)
{
    TYPE result;
    result = n1 + n2;
    return result;
}

void setup()
{
    float x = 2.1;
    float y = 5.6;
    Serial.begin(115200);
    Serial.println(Add(x, y));
}

void loop()
{
}

The error is at line 3. I was mistaken in my first post. The error was in the same place as indicated this time. I'm using a Mega1280 & IDE1.0.2. Any further thoughts/ideas. As I stated above I can get this to compile using atmel studio. It's just easier to do short code tests using the arduino IDE.

Thanks again for any help,
DJ
53  Using Arduino / Programming Questions / Re: Help using templates. on: November 26, 2012, 08:26:22 am
@pYro_65

I did figure out it was the IDE when it compiled using atmel studio. I had no idea how to get it to compile in the arduino IDE. I'll give this a try and let you know if it works for me. smiley-wink

Thanks,
DJ
54  Using Arduino / Programming Questions / Help using templates. on: November 26, 2012, 06:53:02 am
I'm trying to learn templates. smiley-confuse I've been reading a tutorial (Web page: http://www.codeproject.com/Articles/257589/An-Idiots-Guide-to-Cplusplus-Templates-Part-1 ). I copied an example from the tutorial but when I compile I get an error: 'TYPE' does not name a type, it highlights the error line as the first line, the line declaring the template.

Here's my sketch:
Code:
template<class TYPE>
TYPE Add(TYPE n1, TYPE n2)
{
    TYPE result;
    result = n1 + n2;
    return result;
}

void setup()
{
    float x = 2.1;
    float y = 5.6;
    Serial.begin(115200);
    Serial.println(Add(x, y));
}

void loop()
{
}

I thought the purpose of using a template (in this case) was so you didn't have to (explicitly) name a type. Can someone help me understand why I'm getting an error and the author of the tutorial (obviously) is not.

Thanks for your time,
DJ
55  Using Arduino / Programming Questions / Re: A simple question about timers & pin usage. on: November 21, 2012, 09:39:05 pm
Thanks Nick. I guess it's time to learn all about timers.  smiley-eek-blue
I'll do some research and see if I can get all the parts to play nice with each other. If so, I'll post some code for others' in need.

Thanx,
DJ
56  Using Arduino / Programming Questions / Re: A simple question about timers & pin usage. on: November 21, 2012, 01:50:02 pm
Now that I've thought about it, I suppose I could set up software timers using micros() or millis() and poll them.

DJ
57  Using Arduino / Programming Questions / Re: A simple question about timers & pin usage. on: November 21, 2012, 01:46:09 pm
I've got a mega2560 and, believe it or not, I'm using almost every pin. I want to use a timer for timing events between some of the hardware I have attached. The thing is, all of the timer compare match pins are used by hardware devices. Is there any way to use a timer and not have it output on it's related compare match pins?

Thanks for your time,
DJ
58  Using Arduino / Programming Questions / A simple question about timers & pin usage. on: November 21, 2012, 12:56:06 pm
Is it possible to use a timer without affecting any pins?

Thanks for any replies,
DJ
59  Using Arduino / Installation & Troubleshooting / Re: Upload Timeout Error on Mega 2560 - Not Sure What Changed on: November 15, 2012, 12:04:22 pm
I'm having the same problem as Ragnar. Burn a new bootloader, upload one sketch. Then can't upload again (just hangs). Burn bootloader, upload one sketch... Has anyone found the problem or a fix. I'm using Mega2560 R1 and IDE1.0.2 on Windows 7 x64.

DJ
60  Community / Exhibition / Gallery / Re: How to configure the Atmel AVRISP MKii to work with Arduino IDE on: November 10, 2012, 03:10:13 pm
@retrolefty

As velocity101 said, it will not provide power. From reading the user guide
Quote
The Atmel AVRISP mkII supports target voltages from 1.8V up to 5.5V.

Note
VCC must be connected to the target board in order to get correct operation and voltages on the ISP/PDI lines. VCC does not draw any power from the target.
In fact, the AVRISP mkII will not detect the target until it (the target) is powered. Also (I can't find the quote right now), I read somewhere in the user manual that the programmer senses the target voltage and adjusts its self by level shifting to the correct voltage. I do know when you enter the programming dialog it displays the current target voltage.

Hope this info helps.

BTW I was here a few days ago and found a thread on how to get the Arduino core to work under Atmel Studio 6. I followed the instructions and it worked! For me anyway. But after messing around a bit, I'm having some minor troubles. So, I need to find that thread (that's what I was doing when I came upon this thread) and follow the steps again. It's really cool  smiley-cool having all those libraries playing nicely with a full featured IDE with debugging capabilities.  smiley-grin

So, I'm off to search...
DigitalJohnson
Pages: 1 2 3 [4] 5 6 ... 11