Remappable Pins

General discussion on mikroC PRO for PIC32.
Post Reply
Author
Message
Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Remappable Pins

#1 Post by Bill Legge » 07 Jul 2022 09:26

I'm getting to learn the PIC32MZ2048EFH144 mounted on aEasyPICFusionv7 board.
The problem is using I2C2 communications.
Both SCL2 and SDA2 are tied to Vcc (3.3v) by 5k resistors.
As far as I can tell from the manual ALL the I2C pins are NOT RE-MAPPABLE
So SCL2 is Pin 85/RA2
And SDA2 is PIN 86/RA3
Have I go this correct?
Anyone got any working I2C code for some MZ chip _ I'd welcome something to fiddle about with.

Regard Bill Legge in Australia

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: Remappable Pins

#2 Post by hexreader » 10 Jul 2022 21:45

Bill Legge wrote:
07 Jul 2022 09:26
So SCL2 is Pin 85/RA2
And SDA2 is PIN 86/RA3
Yes, that is correct.

I finally have a working project for writing to, and reading on-board EEPROM

Sadly I could only get Software I2C library working

I really cannot work out why I cannot make hardware I2C2 library work.

Attached is working soft library code and non-working hardware code.

Connect terminal program to USB UART A 115200 baud, then Type ? <return> to get started
Attachments
BillMonSoft.zip
(1.36 MiB) Downloaded 43 times
BillMon2.zip
(1.36 MiB) Downloaded 33 times
Start every day with a smile...... (get it over with) :)

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Remappable Pins

#3 Post by Bill Legge » 11 Jul 2022 12:02

Hexreader - as usual - thanks a lot.

I'm working on a GPS/Compass project to assist marking out sporting events(horse trials etc) and fencing - I live in rural Australia - with miles of fencing in every direction.
So far: the GPS bit is good and my 'bright idea' is to use a TEXT-TO-SPEECH interface to direct the marker to the correct spot - any TFT or LCD is totally unreadable in strong sunlight in OZ.
Sort of 'Left a bit, Right a bit' etc.
The TEXT-To-SPEECH is also working good.
But - My Compass 2 Click is not - I'm working on delving into all the registers and ready to hurl it out the window.
I'll dig into your code tomorrow.
My own effort is far too messy to bother anyone else with at the moment.
Luckily Ive got a Picoscope that will de-code I2C and that should help?
Any of the various compass modules offered by Mikro any good/easy to use/accurate etc?
Regards Bill Legge

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: Remappable Pins

#4 Post by hexreader » 11 Jul 2022 15:00

I made a tiny bit of progress....

New version of BillMon2 attached, with i2cEEPROM_RdSingle() final ack changed 0 to 1

I suspect that this may be just a cludge that avoids the issue, rather than a fix, but at least it allows me to read EEPROM and thus see that write does not work.

Logic analyser traces are attached for command "w 22 23"

The file named "good" is for working software I2C BillMon
The file named "bad" is for faulty hardware I2C BillMon2as attached

The bad file seems to missing a stop bit, but of course the I2C decoder may be confused if an earlier bit is wrong.

Stuck for ideas now :cry:
Attachments
badW 2022-07-11 142231.png
badW 2022-07-11 142231.png (8.15 KiB) Viewed 1980 times
GoodW 2022-07-11 142427.png
GoodW 2022-07-11 142427.png (8.54 KiB) Viewed 1980 times
BillMon2.zip
(1.36 MiB) Downloaded 30 times
Start every day with a smile...... (get it over with) :)

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Remappable Pins

#5 Post by Bill Legge » 12 Jul 2022 12:03

I'm using the Compass 2 Click and have attached the page from the manual about the data format - it says 'Little-Endian'.
I'm getting odd results and a few questions:
1. Are the BYTES signed or unsigned? Do I read them as signed bytes or not?
2. From my reading the result is simply obtained by reading the Hi byte - shift left X8 and add the low byte? and reading the 16 bit int as a signed int?
Any advice please?

Bill Legge in Australia
Little Endian.JPG
Little Endian.JPG (139.45 KiB) Viewed 1960 times

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Remappable Pins & Little Endian

#6 Post by Bill Legge » 14 Jul 2022 01:03

Still working on the bytes in the registers in Compass 2 Click - I think the following in correct:
1. Read register named HXL as an unsigned byte.
2. Read register named HXH as an unsigned byte
3. (HXH<<8) + HXL and treat it as a SIGNED INT.
4. Then do the same with the other pairs?
5. What about the three 'sensitivity constants' used to correct the readings - SIGNED or UNSIGNED bytes?
Am I correct?

Bill Legge in Australia

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Remappable Pins

#7 Post by Bill Legge » 28 Jul 2022 12:05

There is certainly something wrong with the PIC32MX I2C functions.
I have attached four functions below:
1. Two use the hardware I2C pins RA2 and RA3 on the clicker2 for PIC32MX.
2. Two use a soft I2C for the same pins - RA2 and RA3

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Function - Soft Write 1 byte to 24LC512 EEPROM using I2C2 MirkoBUS1 left   //
//            Chip addresss is READ addres 1010HHH0 where H is hard wired     //
//            WRITE address = READ address +1 = 1010HHH1                      //
//            data_add is 16 bit number decomposed in this function           //
//            value is the byt to be writtern                                 //
void Soft_Byte_Write_24LC512(char chip_address,unsigned int address, char value){
    Soft_I2C_Start();                                                         //
    Soft_I2C_Write(chip_address);                                             //
    Soft_I2C_Write(address>>8);                                               //
    Soft_I2C_Write(address);                                                  //
    Soft_I2C_Write(value);                                                    //
    Soft_I2C_Stop();                                                          //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////
// Function - Soft Read 1 byte from 24LC512 EEPROM using Soft_I2C MirkoBUS1   //
//            Chip addresss is READ addres 1010HHH0 where H is hard wired     //
//            WRITE address - READ address +1 = 1010HHH1                      //
//            data_add is 16 bit number decomposed in this function           //
//            value is the byt to be writtern                                 //
char Soft_Byte_Read_24LC512(char chip_address,unsigned address ){             //
    char retval;                                                              //
    Soft_I2C_Start();                                                         //
    Soft_I2C_Write(chip_address);                                             //
    Soft_I2C_Write(address>>8);                                               //
    Soft_I2C_Write(address);                                                  //
    Soft_I2C_Start();                                                         //
    Soft_I2C_Write(chip_address+1);   // read address = write address + 1     //
    retval = Soft_I2C_Read(0);                                                //
    Soft_I2C_stop();                                                          //
    return(retval);                                                           //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Function -  Write 1 byte to 24LC512 EEPROM using I2C2 MirkoBUS1 left       //
//            Chip addresss is READ addres 1010HHH0 where H is hard wired     //
//            WRITE address = READ address +1 = 1010HHH1                      //
//            data_add is 16 bit number decomposed in this function           //
//            value is the byt to be writtern                                 //
void Byte_Write_24LC512(char chip_address,unsigned int address, char value){  //
    I2C2_Start();                                                             //
    I2C2_Write(chip_address);                                                 //
    I2C2_Write(address>>8);                                                   //
    I2C2_Write(address);                                                      //
    I2C2_Write(value);                                                        //
    I2C2_Stop();                                                              //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////
// Function - Read 1 byte from 24LC512 EEPROM using I2C2 MirkoBUS1 left       //
//            Chip addresss is READ addres 1010HHH0 where H is hard wired     //
//            WRITE address - READ address +1 = 1010HHH1                      //
//            data_add is 16 bit number decomposed in this function           //
//            value is the byt to be writtern                                 //
char Byte_Read_24LC512(char chip_address,unsigned address ){                  //
    char retval;                                                              //
    I2C2_Start();                                                             //
    I2C2_Write(chip_address);                                                 //
    I2C2_Write(address>>8);                                                   //
    I2C2_Write(address);                                                      //
    I2C2_Restart();                                                           //
    I2C2_Write(chip_address+1);       // read address = write address + 1     //
    retval = I2C2_Read(0);                                                    //
    I2C2_stop();                                                              //
    return(retval);                                                           //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////
The 'soft' I2C works OK.
The hardware I2C does not it transmits the Write function OK but the Read function stuffs things up.
Anyone got any ideas?
I suspect the Microchip MCU - there are some 'Silicon Issues' and other notes about the problem.

Regards Bill Legge in Australia

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Remappable Pins

#8 Post by Bill Legge » 07 Aug 2022 09:18

Some progress - using Compass 4 Click and it works just fine. But some advice/help needed, see end of this post
The registers that hold the magnetic fields are Signed INTS constructed the taking the Hi_Byte<<8 + L0_Byte.
If you are having difficulty with Compass Click 4 note that 'the words' in the Mikro documents
are correct but the circuit diagram does not show how the address pins have been set by default. The correct addresses are:

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// I2C Addresses                                                              //
//  The Mikro chip carrier ties the address pins CAD0=0 and CAD1=0            //
//  So the slave address is 0b00011[CDA1][CAD0][R/W]                          //
//  Adding the CAD0 and CAD1 bits gives bit gives 0b0001000 + R/W bit         //
//  Read address of 0b00011001(19h)                                           //
//  Write address of 0b00011000(18h) //                                       //
//  As usual Read_address = Write_address + 1                                 //
#define AK09915_READ_ADD     0x19        // see above 00011011                //
#define AK09915_WRITE_ADD    0x18        // see above 00011010                //
////////////////////////////////////////////////////////////////////////////////
And the Mikro I2C function work just fine:

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Function - Test if slave is free  I2C2                                     //
void I2C2_ack_polling(char Device_Write_Add){                                 //
    while(1){                                                                 //
        I2C2_Start();                                                         //
        // Returns zero if no errors or 1 if collision                        //
        if (I2C2_Write(Device_Write_Add) == 0) break;                         //
    }                                                                         //
    I2C2_Stop();                                                              //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////
// Function - Register read byte  I2C2                                        //
unsigned short Register_Read(char Device_Write_Add, char register_add){       //
    unsigned short in_byte;                                                   //
    I2C2_ack_polling(Device_Write_Add);                                       //
    I2C2_Start();                                                             //
    I2C2_Write(Device_Write_Add);         // write address                    //                                                             //
    I2C2_Write(register_add);             // register address                 //
    I2C2_Restart();                                                           //
    I2C2_Write(Device_Write_Add+1);       // read address                     //
    in_byte = I2C2_Read(_I2C_NACK);       // NAK                              //
    I2C2_Stop();                                                              //
    return(in_byte);                                                          //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////
// Function - Register write byte                // I2C2                      //
void Register_Write(char Device_Write_Add,       // AK09915_WRITE_ADD         //
                    char register_add,           // Register to be written    //
                    char register_value){        // data to be written        //
    I2C2_ack_polling(Device_Write_Add);                                       //
    I2C2_start();                                                             //
    I2C2_Write(Device_Write_Add);                                             //
    I2C2_Write(register_add);                    // write register address    //
    I2C2_Write(register_value);                  // write data                //
    I2C2_stop();                                                              //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////
And some help please - I've got the three magnetic readings (Signed Ints) Mx, My, Mz
but using atan or atan2 on Mx and My is NOT giving me a bearing.
Other web sites use some more complicated functions e.g:

Code: Select all

// shift and scale
m->x = (m->x - m_min.x) / (m_max.x - m_min.x) * 2 - 1.0;
m->y = (m->y - m_min.y) / (m_max.y - m_min.y) * 2 - 1.0;
m->z = (m->z - m_min.z) / (m_max.z - m_min.z) * 2 - 1.0;
What do I do with the Mx and My to turn them into a bearing?

Regards Bill Legge in Australia

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: Remappable Pins

#9 Post by hexreader » 07 Aug 2022 11:06

Please check the help utility for tan() and atan() library functions - e.g.
Prototype double atan(double f);

Description Function computes the arc tangent of parameter f; that is, the value whose tangent is f. The return value is in radians, between -Π/2 and Π/2 (inclusive).

Example doub = atan(1.0); // doub = 7.853982e-1
tan and atan require parameters that are floating point double variables

Can't help with how to solve your issue until I buy my own compass 4 click, which may be many weeks away
Looks like a fun problem to solve once I have a click board to work with

Me examples seem overly simple IMHO
Start every day with a smile...... (get it over with) :)

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Remappable Pins

#10 Post by Bill Legge » 07 Aug 2022 11:38

Hexreader - thanks.
I think it is necessary to allow for different strengths and sensitivity of the Mx and My fields.
For example if, where I live, the East and North magnetic field strengths are the same then arctan will give the correct answer of 45 degrees bearing.
That seems unlikely to me - so some fractions/normalisation is needed:
1. Take Mx max and Mx min so you have a range for the X direction.
2. Scale and shift so the the range is zero to MAX.
3. Do the same with My and shift/scale so that it's range is also zero to MAX.
4. Then use atan or atan2 to get the bearing.
Now I've typed out my thoughts to you it seems 'obvious.'

I'll have a go at it tomorrow - thanks for prodding my brain into action.

Regards Bill Legge in Australia

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: Remappable Pins

#11 Post by hexreader » 07 Aug 2022 11:42

arctan will give the correct answer of 45 degrees bearing.
Note that returned atan() value will be in radians, not degrees

Good luck :)
Start every day with a smile...... (get it over with) :)

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Remappable Pins

#12 Post by Bill Legge » 09 Aug 2022 11:30

Hexreader - thanks for your help.
The Mikro examples are a bit simple and could do with some further examples of bearing calculation and tit compensation.
I think I'm going to be able to publish code for both in the next few days?
I've worked out the semi-obvious - that the sensitivities of the Mx My and Mz axis must be different and thus
normalisation is essential before using the arctan function to get a bearing.
The code I found in some other site is doing exactly that:
m->x = (m->x - m_min.x) / (m_max.x - m_min.x) * 2 - 1.0;
m->y = (m->y - m_min.y) / (m_max.y - m_min.y) * 2 - 1.0;
m->z = (m->z - m_min.z) / (m_max.z - m_min.z) * 2 - 1.0;

This is called unity-based normalization (thank you Wikipedia) and ensures that the range of each variable is zero to 1.
There are one or two other 'gotchas' in these Clicks - I'm polishing up my crappy code tonight and will get the results out tomorrow/soonish.
I'm a bit embarrassed not to have spotted the 'normalisation.' Many years ago I used to be good at maths but not any more.
My C coding is self taught any lacks any polish or elegance so I'm happy to publish my best attempt and invite anyone to tart it up.

Regards Bill Legge in Australia

Post Reply

Return to “mikroC PRO for PIC32 General”