Show Posts
Pages: [1] 2
1  Products / Arduino Due / Updated version: 8 channels, many more pins on: June 16, 2013, 02:53:54 am
Hello everyone!

After reading the data sheet properly, I've updated my hardware servo library to use all available PWM channels and all available output pins, see the following table. This overrides the Arduino distribution variant.cpp pin configuration g_APinDescription[] for the Due, which is far from complete.
PWM PinChannel
67
76
85
94
17/RX21
340
361
382
403
432
A81
A92
A103
DAC10
CANTX3

This means you can output a servo signal to any of the above pins, but only one pin per channel. For example, you cannot output two different servo signals on pin A10 and CANTX at the same time because they are both driven by the hardware PWM channel 3.

It is possible to output a servo/PWM signal on a bunch of other pins as well by using the complementary PWM signal for each channel but the above pins suit me well enough not to warrant writing the code for handling inversion of duty cycle parameters (and thereby increasing the runtime size of the code)

To use the library, simply unpack the ZIP into your libraries folder, restart Arduino and open the DueServo example Sweep.
2  Products / Arduino Due / Re: I2C + DMA on: May 02, 2013, 07:10:42 am
Added corrections to the code above, now setting the STOP flag prior to transferring data. This code works correct only for 1-byte transfers, see top of post.
3  Products / Arduino Due / Re: I2C + DMA on: May 01, 2013, 02:11:00 pm
EDIT2: Warning: this code does not correctly set the stop condition. It should be set prior to the last byte being transferred. For an N-byte transfer, we can transfer N-1 bytes by PDC, then interrupt, set the STOP flag and then send the last byte, also by PDC.
I've edited this code to always set the stop condition before activating the PDC, which works for 1-byte transfers. You can put it together or I might post my library when it's finished smiley
/EDIT

I've got I2C working with PDC. It wasn't easy and the code is not pretty (yet) but it should get you started!

I'm writing an event-driven architecture where multiple drivers can communicate with one device each on the same I2C bus. There's some work left but when I'm done I should be able to run multiple I2C devices with nearly zero CPU overhead smiley

Code:
#include <Arduino.h>
#define DeviceID                0x34
#define DeviceAddress           0x68
#define MPU6050_RA_WHO_AM_I     0x75
#define MPU6050_WHO_AM_I_BIT    6
#define MPU6050_WHO_AM_I_LENGTH 6
#define TWI_CLOCK               100000
uint8_t count = 0;
bool didWeRead;
enum ServiceState : uint8_t {
        FinishedReading,
        FinishedWriting,
        FinishedWaiting,
};

static inline void TWI_PDCWrite(uint8_t *data, uint16_t count) {
        WIRE_INTERFACE->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
        WIRE_INTERFACE->TWI_TPR = (RwReg)data;
        WIRE_INTERFACE->TWI_TCR = count;
        WIRE_INTERFACE->TWI_TNPR = 0;
        WIRE_INTERFACE->TWI_TNCR = 0;
}
static inline void TWI_PDCRead(uint8_t *data, uint16_t count) {
        WIRE_INTERFACE->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
        WIRE_INTERFACE->TWI_RPR = (RwReg)data;
        WIRE_INTERFACE->TWI_RCR = count;
        WIRE_INTERFACE->TWI_RNPR = 0;
        WIRE_INTERFACE->TWI_RNCR = 0;
}

static inline void TWI_MasterModeWrite(uint8_t deviceAddress) {
        WIRE_INTERFACE->TWI_MMR = TWI_MMR_IADRSZ_NONE | TWI_MMR_DADR(deviceAddress);
        WIRE_INTERFACE->TWI_CR = TWI_CR_MSEN;
}
static inline void TWI_MasterModeRead(uint8_t deviceAddress) {
        WIRE_INTERFACE->TWI_MMR = TWI_MMR_IADRSZ_NONE | TWI_MMR_DADR(deviceAddress) | TWI_MMR_MREAD;
        WIRE_INTERFACE->TWI_CR = TWI_CR_MSEN;
}

static inline void TWI_Write() {
        didWeRead = false;
        WIRE_INTERFACE->TWI_CR = TWI_CR_START | TWI_CR_STOP;
        WIRE_INTERFACE->TWI_IER = TWI_IER_ENDTX;
        WIRE_INTERFACE->TWI_PTCR = TWI_PTCR_TXTEN;
}
static inline void TWI_Read() {
        didWeRead = true;
        WIRE_INTERFACE->TWI_CR = TWI_CR_START | TWI_CR_STOP;
        WIRE_INTERFACE->TWI_IER = TWI_IER_ENDRX;
        WIRE_INTERFACE->TWI_PTCR = TWI_PTCR_RXTEN;
}

void write() {
        TWI_PDCWrite(&count, 1);
        TWI_MasterModeWrite(DeviceAddress);
        TWI_Write();
        count++;
}
uint8_t received[8];
void read() {
        TWI_PDCRead(received, 8);
        TWI_MasterModeRead(DeviceAddress);
        TWI_Read();
}
void InitializeTWI() {
        pmc_enable_periph_clk(WIRE_INTERFACE_ID);
        PIO_Configure(
                        g_APinDescription[PIN_WIRE_SDA].pPort,
                        g_APinDescription[PIN_WIRE_SDA].ulPinType,
                        g_APinDescription[PIN_WIRE_SDA].ulPin,
                        g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
        PIO_Configure(
                        g_APinDescription[PIN_WIRE_SCL].pPort,
                        g_APinDescription[PIN_WIRE_SCL].ulPinType,
                        g_APinDescription[PIN_WIRE_SCL].ulPin,
                        g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);

        NVIC_DisableIRQ(TWI1_IRQn);
        NVIC_ClearPendingIRQ(TWI1_IRQn);
        NVIC_SetPriority(TWI1_IRQn, 0);
        NVIC_EnableIRQ(TWI1_IRQn);

        // Disable PDC channel
        WIRE_INTERFACE->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;

        TWI_ConfigureMaster(WIRE_INTERFACE, TWI_CLOCK, VARIANT_MCK);
}


void setup() {
        SerialUSB.begin(115200);
        Serial.begin(115200);
        InitializeTWI();
}

void loop() {
        write();
        delay(1000);
        //read();
        //delay(1000);
}

void TWI1_Handler() {
        int sr = WIRE_INTERFACE->TWI_SR;
        WIRE_INTERFACE->TWI_IDR = TWI_IDR_ENDTX | TWI_IDR_ENDRX;
        WIRE_INTERFACE->TWI_PTCR = TWI_PTCR_TXTDIS | TWI_PTCR_RXTDIS;
        WIRE_INTERFACE->TWI_CR = TWI_CR_STOP;
        if(didWeRead) {
                Serial.print("Read");
                for(int i = 0; i < 8; i++) {
                        Serial.print(" ");
                        Serial.print(received[i]);
                }
                Serial.println("");
        } else {
                long time = micros();
                while(!(WIRE_INTERFACE->TWI_SR & TWI_SR_TXRDY));
                time = micros() - time;
                Serial.print("Iterations: ");
                Serial.println(time);
                read();
        }
}

EDIT: I'm building with make, so perhaps there are some differences (like #include <Arduino.h>)
4  Products / Arduino Due / Re: Arduino Due and Galaxy Nexus Problem with ADK on: November 27, 2012, 07:37:33 am
Please let me know if you find a solution!

I've been playing around with modifications to the USBHost library to make it work better but I simply don't have the time to rewrite it properly! Turning on TRACE_USBHOST in Usb.h makes it work much much better, but at the expense of way too much debug output over serial. I believe it's simply a timing issue: the new Android devices are too slow, or the Due is too fast. Debugging slows down the sketch, thereby giving the Android time to switch to Accessory mode.
5  Products / Arduino Due / Re: Hardware Servo: Example Code on: November 26, 2012, 04:28:46 am
I'm glad I could help smiley

And thank you for a very good explanation of the parameters! I made PWM_CLOCK, PWM_PERIOD, PWM_DUTY_MIN and PWM_DUTY_MAX constants inside the library because they need no modification if you use the code as a servo library.

But in your case and any similar ones it might be better to make them parameters to the writeMicros() method so the caller can set them freely. Also a rename of the methods might be proper, because if you modify PWM_CLOCK it will no longer be microseconds you write. initPWM() and writePWM, perhaps?
Of course, PWM_DUTY_MIN and PWM_DUTY_MAX are only relevant for the servo implementation, you will most probably want to remove them completely or modify them to suit your needs.

/Sebastian
6  Products / Arduino Due / Re: Timer Interrupts on Due on: November 25, 2012, 09:09:35 am
Also, what are the pins in the table for?
Good question! If I understood everything correctly, the pins in the table are where you could output the clock of that timer/counter if you wanted to use it for something else than internal software interrupts.
Basically you can set up the hardware counter to output a clock signal. For example, TC0 channel 0 could be used to output a clock on the Arduino pin 2 or 13. So if you use TC0 channel 0 for your timer, you would not be able to output a clock on those pins (except using the frequency you set up the channel for).
That is why it would be better to use TC1 channels 0, 1 or 2 primarily for this kind of interrupt, as their output is not mapped to any of the Arduino pins and therefore does not limit any of your physically mapped outputs.
7  Products / Arduino Due / Re: Arduino Due and ADK on: November 17, 2012, 01:42:47 pm
OK, I hope this can help figure it out.
Part of the problem, at least with the Note II, is timing. The error I get when debugging the USB host code is a timeout (error code 0xFF) on one of the USB packets. This doesn't happen if (for instance) I output a whole lot of serial data to slow the sketch down. It is not enough to add a delay() in the main loop, since the whole thing fails if we delay() too much as well. Adding a delay(50) between each call to Usb.Task() and a few delay(100) at strategic places inside USBHost::Task() makes it work pretty reliably. I haven't had the time to make it work well yet or I would post code.

Another issue is the fact that the USB code stops working if you soft-reset the Due, such as by opening the serial console after a sketch has started running. This can be worked around by uploading the sketch, then unplugging the Due and as fast as humanly possible after plugging it in, you open the debug console. I guess this works because you can actually soft-reset the Due before the USB initialization takes place, and therefore it doesn't try to initialize it twice.

If you have the phone connected to the Due and your sketch either crashes or your code is timed wrong, you might confuse the USB stack on the Android. This is only solved by rebooting. So if it stops working, you might get it running again by simply rebooting the Android. I power-cycle the Due between every run.

I ran a modified version of the ADK2012 sketch and library, compiled with the ADK2012 version of the IDE. This powered up the USB port even when running on external power, so there's nothing wrong with the hardware. There has to be a mistake somewhere in the library, I just don't have enough knowledge to find it!
8  Products / Arduino Due / Re: Arduino Due and ADK on: November 16, 2012, 06:42:18 pm
Whitewater I have the exact same problem. Some times I get it to connected state and can transfer data successfully but then other times it just doesn't work.
I haven't figured out what's wrong yet. I've had varying degrees of success on different devices. One sketch would work fine with bi-directional communication on one device but only unidirectional on the other. Another sketch would work on both. Today I only had one successful run out of perhaps ten or fifteen attempts with different very simple sketches.
I always lose packets when I try sending them them too fast from the Due, like three in a row without any time between.

And the power is weird, isn't it? Of course it should power the USB port even if it's running on an external power source!
9  Products / Arduino Due / Re: Arduino Due and ADK on: November 07, 2012, 04:23:10 pm
I use a cable like this one on the Due side: http://www.ebay.com/itm/Micro-USB-Host-OTG-Cable-W-USB-power-Samsung-phone-i9100-i9300-i9220-9250-/150928276246?_trksid=p2047675.m1850&_trkparms=aid%3D222002%26algo%3DSIC.FIT%26ao%3D1%26asc%3D11%26meid%3D3299974227435379446%26pid%3D100011%26prg%3D1005%26rk%3D1%26sd%3D110931117836%26
It plugs into either the programming port or the native port. On the other end I use a normal USB charging cable (#1 in your list).

Is it simply because I'm using the wrong cable? But the host port powers up when the programming port is connected to the PC!

EDIT: The special cable acts like a normal OTG cable with the option of external power supply (not used in this case)
10  Products / Arduino Due / Re: SPI or SD library problem? on: November 07, 2012, 08:33:37 am
I can't do the test because the example doesn't compile, besides I don't have an SD slot attached..
Code:
listfiles:26: error: variable or field 'printDirectory' declared void
listfiles:26: error: 'File' was not declared in this scope
listfiles:26: error: expected primary-expression before 'int'
listfiles:23: error: 'File' does not name a type
listfiles.ino: In function 'void setup()':
listfiles:41: error: 'SD' was not declared in this scope
listfiles:47: error: 'root' was not declared in this scope
listfiles:47: error: 'SD' was not declared in this scope
listfiles:49: error: 'printDirectory' was not declared in this scope
listfiles.ino: At global scope:
listfiles:59: error: variable or field 'printDirectory' declared void
listfiles:59: error: 'File' was not declared in this scope
listfiles:59: error: expected primary-expression before 'int'
11  Products / Arduino Due / Re: Arduino Due and ADK on: November 07, 2012, 08:03:53 am
Does the phone get power from the Due, or nothing? How do you power the Due?
I think it might be a power problem because my Desire S doesn't connect (only charge) when I'm powering the Due over computer USB while charging another phone from the same USB hub.

Another power problem: the USB host port doesn't seem to power up at all when I'm running the Due on 12V external power. Is there a call I need to make to enable the USB host power?
And it gets better: while the host port appears to be dead, the programming port is powered; I can charge my phone over it! It's not supposed to power the programming port, right?
12  Products / Arduino Due / Re: Arduino Due Task Scheduler on: November 07, 2012, 03:07:33 am
micnossub: yield() will let other competing threads execute and when they've had a go, continue this one as soon as possible.


It's a great ambition Paul!

I thought about the same problem with allocating stacks. The size limit isn't a problem, as you're exposing it in the start calls. If some library needs more, sooner or later that's going to pop up on their tutorials. Basically right now all the old libraries are used to having what... 4K or SRAM? If you gave every thread 4K you could have 24 threads on the Due (OK, probably more like 16 but anyway). Not many will do more than that and if they do, I think they'd know how to tweak their stack sizes. Hmm, it IS a problem on the AVR platforms, though...

I've done it differently in my application, sharing stack spaces and switching tasks upon the return of the last, ie return wait(20). Now that's basically trying to do the same thing you're doing but instead of putting "yield()" calls on strategic places in blocking libraries, I would need to rewrite them to be non-blocking. It's not impossible, every library I've seen can be rewritten since the interfaces are all wrapping code like "while(!done()) ; return result;". This is crazy to me, but that's the way it is. It's easier for beginners and that's what Arduino is all about.

So  your way is better. Easier to get working quickly and more in line with the Arduino goal. I guess we could help each other out - I'll rewrite my application to use your library, then I can help you with testing and adding yield() calls to the other libraries I use: USBHost with ADK, Wire, and a bunch of Wire-based I2C drivers.
13  Products / Arduino Due / Re: SPI or SD library problem? on: November 06, 2012, 12:55:38 pm
Are you using the programming port of the Due (the one next to the power plug, should work even if the ARM program has crashed) or the native port?
14  Products / Arduino Due / Re: Arduino Due Task Scheduler on: November 06, 2012, 12:30:31 pm
Looking at how they've rewritten the delay() call to use yield() under the hood in the 1.5.1 release and the ambitions for 1.5.2 (on the mailing list) I'd say they're pretty serious about this library.

I think it looks awesome and I'll start working with it as soon as I have the time to rewrite my home-brew scheduler! smiley
15  Products / Arduino Due / Re: Arduino Due and ADK on: November 06, 2012, 11:32:47 am
It never occurred to me to try all of them before, but here goes:

ManufacturerNameAndroidState
HTCDesire S2.3.7, CyanogenMod 7.1Works
AsusTransformer Prime TF2014.1.1Works
SamsungGalaxy Tab 7"4.1.1, CyanogenMod nightlyOnly charging
SamsungGalaxy Tab 2 10.1"4.0.4Works
SamsungGalaxy Note 24.1.1Only charging
Google/SamsungGalaxy Nexus4.?Only charging

EDIT: I don't think it's an Android version issue. I've heard the manufacturers can choose to disable the ADK feature (of course they can). I just never thought they would. Why?
Pages: [1] 2