Standard libraries unknown in IDE V1.5.1r2

It looks like an assembly language reference to an I/O port register. Whatever it does in AVR is not likely the same in Due.

Picking this function:

uint8_t OneWire::reset(void)
{
	IO_REG_TYPE mask = bitmask;
	volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
	uint8_t r;
	uint8_t retries = 125;

	noInterrupts();
	DIRECT_MODE_INPUT(reg, mask);
	interrupts();
	// wait until the wire is high... just in case
	do {
		if (--retries == 0) return 0;
		delayMicroseconds(2);
	} while ( !DIRECT_READ(reg, mask));

	noInterrupts();
	DIRECT_WRITE_LOW(reg, mask);
	DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
	interrupts();
	delayMicroseconds(500);
	noInterrupts();
	DIRECT_MODE_INPUT(reg, mask);	// allow it to float
	delayMicroseconds(80);
	r = !DIRECT_READ(reg, mask);
	interrupts();
	delayMicroseconds(420);
	return r;
}

this line

volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;

Seems to be declaring 2 vars of IO_REG_TYPE (beeing uint32_t by macro defenition previously)

*reg
IO_REG_ASM

But I don't understand why the IO_REG_ASM.

Shouldn't this line be just:

volatile IO_REG_TYPE *reg = baseReg;

?

Not able to help you much here. I did find this on Google. There are some hits using just the IO_REG_ASM search term. Keep in mind that the libraries are dealing with 8 bit AVR processors and we're trying to make them run with a Due.

I also found this item using the search term asm("r31"). It's a register number which has special pointer capabilities when used in pairs. This is AVR hardware specific so the Due is likely much different.

http://www.avr-asm-tutorial.net/avr_en/beginner/REGISTER.html

The register structure is entirely different. I'm putting mine on the shelf until this is all sorted out.

Humm, this might have something to do with interrupts usage...

I'll try to dig on that, thank you for the links.

Hi again.

I've changed the defines to the code bellow:

#elif defined(__SAM3X8E__)
#define PIN_TO_BASEREG(pin)             (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask)         ((*(base)) & (mask))
#define DIRECT_MODE_INPUT(base, mask)   (base->PIO_OER &= ~mask)
#define DIRECT_MODE_OUTPUT(base, mask)  (base->PIO_OER |= mask)
#define DIRECT_WRITE_LOW(base, mask)    ((*(base)) &= ~mask)
#define DIRECT_WRITE_HIGH(base, mask)   ((*(base)) |= mask)
#include "pgmspace.h"

Right now I'm stuck with:

#define DIRECT_MODE_INPUT(base, mask)   (base->PIO_OER &= ~mask)
#define DIRECT_MODE_OUTPUT(base, mask)  (base->PIO_OER |= mask)

The compiler complains that he doens't know member PIO_OER.

I'm looking in the files for this structures but I'm not finding them.

Anyone knows were these structures are?

The idea here, is to make the pin output, or input. If I recall right, this is done with OER.

I've previously used this registers in UTFT lib but in this format:

		REG_PIOX_OER=0xXXXXX

The errors I'm getting from compiler:

"
D:\Docs\Arduino\arduino-1.5.1r2_teste\libraries\OneWire\OneWire.cpp: In member function 'uint8_t OneWire::reset()':
D:\Docs\Arduino\arduino-1.5.1r2_teste\libraries\OneWire\OneWire.cpp:128: error: request for member 'PIO_OER' in '* reg', which is of non-class type 'volatile long unsigned int'
D:\Docs\Arduino\arduino-1.5.1r2_teste\libraries\OneWire\OneWire.cpp:138: error: request for member 'PIO_OER' in '* reg', which is of non-class type 'volatile long unsigned int'
D:\Docs\Arduino\arduino-1.5.1r2_teste\libraries\OneWire\OneWire.cpp:142: error: request for member 'PIO_OER' in '* reg', which is of non-class type 'volatile long unsigned int'
"

Help appreciated. :wink:

PIO_OER ("Output Enable Register") is used in several versions of file component_pio.h. Look in the folders below:

... arduino-1.5.1r2\hardware\arduino\sam\system\CMSIS\Device\ATMEL

HTH,
Jim

Well, still no luck..

I've set all the registers in place same way has the other defines, but no go.

#elif defined(__SAM3X8E__)
#define PIN_TO_BASEREG(pin)             (&(digitalPinToPort(pin)->PIO_PER)) //to get Base PORT address
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask)         (((*(base+0x3c)) & mask) ? 1 : 0)	/*(Pio Offset: 0x003C) Pin Data Status Register */
#define DIRECT_MODE_INPUT(base, mask)   ((*(base+0x14)) & mask) 	/*(Pio Offset: 0x0014) Output Disable Register */
#define DIRECT_MODE_OUTPUT(base, mask)  ((*(base+0x10)) & mask)		/*(Pio Offset: 0x0010) Output Enable Register */
#define DIRECT_WRITE_LOW(base, mask)    ((*(base+0x34)) & mask)		/*(Pio Offset: 0x0034) Clear Output Data Register */
#define DIRECT_WRITE_HIGH(base, mask)   ((*(base+0x30)) & mask)		/*(Pio Offset: 0x0030) Set Output Data Register */
#include "pgmspace.h"

By the way, in the line

#define DIRECT_READ(base, mask) ((((base+0x3c)) & mask) ? 1 : 0) /(Pio Offset: 0x003C) Pin Data Status Register */

what is the meaning of

 ? 1 : 0

?

That's a conditional assignment statement. My link to Wikipedia won't print correctly. Do a search for "C++ ?:"

This link will work.

Let's look at the line.

#define DIRECT_READ(base, mask) ((((base+0x3c)) & mask) ? 1 : 0) /(Pio Offset: 0x003C) Pin Data Status Register */

The line has four parts.

Part 1 is #define DIRECT_READ(base, mask) // The part receiving a value

Part 2 is (((*(base+0x3c)) & mask) ? // A conditional test, true or false

Part 3 is 1: // Value assigned if test is true

Part 4 is 0 // Value assigned if test is false

This is what happens. If part 2 is true then part 1 receives part 3(1). If part 2 is false then part 1 receives part 4(0).

It's the same as:

if( part2 == true )
Part 1 has a 1 appended to the end
else
Part 1 has a 0 appended to the end

Ok, thank you for the explanation.

Well, this should work, I'm clueless...

I'll move for a simple test program with onewire and see what happen. Just in the event that the problem is my program and not the lib...

interrupts()
and
nointerrupts()

Are system functions to enable and disable interrupts at a given time, right?

Right, but the spelling of the second one is noInterrupts();

http://arduino.cc/en/Reference/NoInterrupts

The math with pointers is failing. I try to add the offset to the base register and it gets a value that I can't explain.

I'm using pin 7 of due.

For this pin, the port address is 400E1200 and PDSR register is 400E123C. This is taken from datasheet.

I've added Serial.println to the reset function to see the backstage.

uint8_t OneWire::reset(void)
{
	IO_REG_TYPE mask = bitmask;
	//volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
	volatile IO_REG_TYPE *reg = baseReg;
	//volatile IO_REG_TYPE *regout = baseOutReg;
	Serial.println((long)(&(digitalPinToPort(7)->PIO_PER)),HEX);
	Serial.println((long)(reg),HEX);
	Serial.println((long)(bitmask),HEX);
	volatile uint32_t *value=reg+1;
	Serial.println((uint32_t)value,HEX);
	uint8_t r;
	uint8_t retries = 125;

	noInterrupts();
	DIRECT_MODE_INPUT(reg, mask);
	Serial.println(((*(reg+0x3c))),HEX);

From this serial.print i get:

for -> Serial.println((long)(&(digitalPinToPort(7)->PIO_PER)),HEX);

I have 400E1200

for -> Serial.println((long)(reg),HEX);

I also have 400E1200

for -> Serial.println((long)(bitmask),HEX);

I have 800000

for - > Serial.println((uint32_t)value,HEX);

I have 400E1204 !!!!!!!!!!!!!!

Remenber that I've done this one line before:

volatile uint32_t *value=reg+1;

Why I don't have 400E1201 ????? :astonished:

Ok, I'll answer myself... :smiley:

It's because the var that is pointed is from uint32_t type (4 bytes). So increasing 1, is in fact, increasing 4 positions.

I've fixed this this way:

#elif defined(__SAM3X8E__)
#define PIN_TO_BASEREG(pin)             (&(digitalPinToPort(pin)->PIO_PER)) //to get Base PORT address
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask)         (((*(base+(0x3c/4))) & mask) ? 1 : 0)	/*(Pio Offset: 0x003C) Pin Data Status Register */
#define DIRECT_MODE_INPUT(base, mask)   ((*(base+(0x14/4))) & mask) 	/*(Pio Offset: 0x0014) Output Disable Register */
#define DIRECT_MODE_OUTPUT(base, mask)  ((*(base+(0x10/4))) & mask)		/*(Pio Offset: 0x0010) Output Enable Register */
#define DIRECT_WRITE_LOW(base, mask)    ((*(base+(0x34/4))) & mask)		/*(Pio Offset: 0x0034) Clear Output Data Register */
#define DIRECT_WRITE_HIGH(base, mask)   ((*(base+(0x30/4))) & mask)		/*(Pio Offset: 0x0030) Set Output Data Register */
#include "pgmspace.h"

But still no temp readings...

Ok ok.

WORKINGGGGGGGGGGGGGGGG!!!!!!!!!

Just add this to the onewire.h:

#elif defined(__SAM3X8E__)
#define PIN_TO_BASEREG(pin)             (&(digitalPinToPort(pin)->PIO_PER)) //to get Base PORT address
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask)         (((*(base+15)) & (mask)) ? 1 : 0) 	/*(Pio Offset: 0x003C) Pin Data Status Register */
#define DIRECT_MODE_INPUT(base, mask)   ((*(base+5)) = (mask)) 	/*(Pio Offset: 0x0014) Output Disable Register */
#define DIRECT_MODE_OUTPUT(base, mask)  ((*(base+4)) = (mask))		/*(Pio Offset: 0x0010) Output Enable Register */
#define DIRECT_WRITE_LOW(base, mask)    ((*(base+13)) = (mask))		/*(Pio Offset: 0x0034) Clear Output Data Register */
#define DIRECT_WRITE_HIGH(base, mask)   ((*(base+12)) = (mask))		/*(Pio Offset: 0x0030) Set Output Data Register */
#include "pgmspace.h"

Final code should look like this:

#if defined(__AVR__)
#define PIN_TO_BASEREG(pin)             (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint8_t
#define IO_REG_ASM asm("r30")
#define DIRECT_READ(base, mask)         (((*(base)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask)   ((*(base+1)) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask)  ((*(base+1)) |= (mask))
#define DIRECT_WRITE_LOW(base, mask)    ((*(base+2)) &= ~(mask))
#define DIRECT_WRITE_HIGH(base, mask)   ((*(base+2)) |= (mask))

#elif defined(__SAM3X8E__)
#define PIN_TO_BASEREG(pin)             (&(digitalPinToPort(pin)->PIO_PER)) //to get Base PORT address
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask)         (((*(base+15)) & (mask)) ? 1 : 0) 	/*(Pio Offset: 0x003C) Pin Data Status Register */
#define DIRECT_MODE_INPUT(base, mask)   ((*(base+5)) = (mask)) 	/*(Pio Offset: 0x0014) Output Disable Register */
#define DIRECT_MODE_OUTPUT(base, mask)  ((*(base+4)) = (mask))		/*(Pio Offset: 0x0010) Output Enable Register */
#define DIRECT_WRITE_LOW(base, mask)    ((*(base+13)) = (mask))		/*(Pio Offset: 0x0034) Clear Output Data Register */
#define DIRECT_WRITE_HIGH(base, mask)   ((*(base+12)) = (mask))		/*(Pio Offset: 0x0030) Set Output Data Register */
#include "pgmspace.h" 

#elif defined(__PIC32MX__)
//- #include <plib.h>  // is this necessary?
#define PIN_TO_BASEREG(pin)             (portModeRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask)         (((*(base+4)) & (mask)) ? 1 : 0)  //PORTX + 0x10
#define DIRECT_MODE_INPUT(base, mask)   ((*(base+2)) = (mask))            //TRISXSET + 0x08
#define DIRECT_MODE_OUTPUT(base, mask)  ((*(base+1)) = (mask))            //TRISXCLR + 0x04
#define DIRECT_WRITE_LOW(base, mask)    ((*(base+8+1)) = (mask))          //LATXCLR  + 0x24
#define DIRECT_WRITE_HIGH(base, mask)   ((*(base+8+2)) = (mask))          //LATXSET + 0x28

#else
#error "Please define I/O register types here"
#endif

The difference is the equal sine instead the logical AND.

But, I still don't understand why it works this way...

Remenber, the pgmspace.h is in a few older posts in this thread.

Can someone test this also?

It worked for me for a while, but then started to give errors.

After a while, lost communication with prob.

Thanks

Hi again.

The problem is around the timers for read and write timeslots. The datasheet from the probe says that the timeslots should be at least 60us long, and this works for arduino and chipkit. but I'm already near 80us and still get one error sometimes, but very spaced.

I'm tweaking those timers to see if i can get 100% success. I'm also considering that the problem may be because I'm reading the prob in the loop, for every cycle I check the probe. Due is a lot faster then Mega, and because of this, maybe I'm getting stuck in some hardware limit of the probe regarding speed. But chipkit is also fast, almost same clock speed and no errors with it.

I'll continue to increase time slot size to see if it gets 100% success. If no more improvements this way, I'll try to see what happens if I start to check the probe once every second for example.

I'll keep posting.

Regards,

Joao