Wrongly READ BITs from peripheral, error? Oshonsoft BASIC

Thread Starter

camerart

Joined Feb 25, 2013
2,761
Hi,
I'm using Oshonsoft to program PIC, and there are a couple of '2's compliment' sections. One of these sections occasionally gives an error.

Looking at the BITs, also trying subtracion of the results, it appears that there is a carry over error.

I hope I have the settings at BURST READ of peripherals, which may be where the problem lies.

How can a carry over error found? (the program is too long to post)
Camerart.
 

Papabravo

Joined Feb 24, 2006
17,240
It is a bit difficult to know what you are talking about because your statements lack precision and context.
I don't know what a 2's complement section refers to. Elementary arithmetic operations, like addition and subtraction are done by the hardware using a 2's complement representation for positive and negative numbers. I do not think you are talking about these elementary operation being done in the hardware. What I think you are talking about are multibyte (multiword) operations where the state of the carry flag must be preserved and included in each operation after the first.

In the assembly language for the PIC there are two separate add instructions. The first kind of add instruction just adds two numbers together with the assumption that there is no carry into the least significant bit. The second kind of add instruction is the "add with carry" which adds three things together, two numbers and a carry which can be either 0 or 1. The easiest way to detect a potential problem is to look at the assembly language code to see if the rules for multi-byte operations are being followed. The alternative is that you have to find an actual example of where the mistake happens.

Subtraction works the same way except the 'carry' from addition now serves as a 'borrow' for subtraction. In multibyte operations a "subtract with borrow" must be used after the subtraction of the lowest order bytes.
 

Thread Starter

camerart

Joined Feb 25, 2013
2,761
It is a bit difficult to know what you are talking about because your statements lack precision and context.
Hi P,
That makes two of us:)

This error has just materialised, so it's difficult for me to know where the error starts.

I'm READing a compass peripheral via SPI.

The results show degrees, which are calculated using 2's compliment, but the error may not be that.

It appears that 1x of the READ BITS is wrong occasionally, giving an error, that if the error number is subtracted from the correct string of READings, then this points to a BIT READ error.

I can't really describe it any better.

The calculation uses the shaded sections of the attached graph. I only seem to get the error in certain orientations of the Peripheral.
C
 

Attachments

Papabravo

Joined Feb 24, 2006
17,240
You did not specify the format of the data you are reading.
It looks like you have two numbers, each of which is in the range [-100, +100] which you must decode into a direction by looking at some function of the two numbers, Is that correct?
What does your algorithm look like?
 

Thread Starter

camerart

Joined Feb 25, 2013
2,761
You did not specify the format of the data you are reading.
It looks like you have two numbers, each of which is in the range [-100, +100] which you must decode into a direction by looking at some function of the two numbers, Is that correct?
What does your algorithm look like?
Hi P,
It has been over a year since I did this bit, but I think there are 2x BYTEs plus a +- BIT, and maybe you will figure it out from the Algorithm, before I remember how it works :)


Here's the algorithm:
C.

Code:
'READ COMPASS XYZ REGISTER
Proc read_compass()
Toggle yled
    For i = 0 To 18  '5  'READ ALL (except RSV.  Is TS1 and 2 OK?)
        compss_cs = 0  'CHIP SELECT COMPASS ON
            rd_adr = 0x80 + i  '00=WRITE 80=READ
            WaitUs 1
            SSPBUF = rd_adr
            While Not SSPSTAT.BF
            Wend
            WaitUs 1
            SSPBUF = 0  'Dummy BYTE
            While Not SSPSTAT.BF
            Wend
            periph_rd = SSPBUF
            b(i) = periph_rd
        compss_cs = 1  'CHIP SELECT COMPASS OFF
    Next i
       
    w1a_raw = b(0)
    info_raw = b(1)
    st_1_raw = b(2)

    x_raw.LB = b(3)  'BYTE
    x_raw.HB = b(4)  'BYTE
    y_raw.LB = b(5)
    y_raw.HB = b(6)
    z_raw.LB = b(7)
    z_raw.HB = b(8)

    x_nc = x_raw  'SINGLE = WORD
    y_nc = y_raw
    z_nc = z_raw

    st_2_raw = b(9)
    cntl_1_raw = b(10)
    cntl_2_raw = b(11)
    astc_raw = b(12)

    i2c_dis_raw = b(15)  'i2c???????
    asax_raw = b(16)
    asay_raw = b(17)
    asaz_raw = b(18)

    str_asax = #asax_raw
    str_asay = #asay_raw
    str_asaz = #asaz_raw

    str_w1a = #w1a
    str_info = #info
    str_st_1 = #st_1

'2'S COMPLIMENT CALC
    If x_nc > 32767 Then  'ALL SINGLES (e,g, x_nc = not calibrated)
        x_nc = x_nc - 65536
    Endif
    If y_nc > 32767 Then
        y_nc = y_nc - 65536
    Endif
    If z_nc > 32767 Then
        z_nc = z_nc - 65536
    Endif
'2'S COMPLIMENT CALC
'BIAS CALC
    x_0 = x_nc - b_x  'ALL SINGLES
    y_0 = y_nc - b_y
    z_0 = z_nc - b_z

    x_c = (m11 * x_0) + (m12 * y_0) + (m13 * z_0)
    y_c = (m21 * x_0) + (m22 * y_0) + (m23 * z_0)
    z_c = (m31 * x_0) + (m32 * y_0) + (m33 * z_0)

    str_x = #x_c  'STRING = SINGLE
    str_y = #y_c
    str_z = #z_c

    str_cntl_1 = #cntl_1_raw

    DEG = 360 - atn(x_c, y_c)  'FUNC CALL.  str_deg = #atn (e,g, X_C...CALIBRATED)
    str_deg = #DEG
End Proc                                        
   
Proc show_compass()
    Hserout "COMP DEG  ", str_deg, CrLf
End Proc                                        

'DEGREE CALC
'Result in degrees clockwise from North = 0
Function atn(x_c As Single, y_c As Single) As Single

Const bdeg = 0.596227  'b = 0.596227
Dim tang As Single
Dim at1 As Single
Dim at2 As Single

    If y_c = 0 Then
        y_c = y_c + 0.000001  'to prevent divide by zero
    Endif

    tang = x_c / y_c
    at1 = 90 * tang * (bdeg + tang) / (1 + 2 * bdeg * tang + tang * tang)
    at2 = -90 * tang * (bdeg - tang) / (1 - 2 * bdeg * tang + tang * tang)

    If x_c >= 0 Then
        If y_c > 0 Then
            atn = at1
        Endif
    Endif

    If x_c >= 0 Then
        If y_c < 0 Then
            atn = 180 - at2
        Endif
    Endif

    If x_c < 0 Then
    If y_c < 0 Then
            atn = 180 + at1
        Endif
    Endif

    If y_c > 0 Then
        If x_c <= 0 Then
            atn = 360 - at2
        Endif
    Endif
End Function
 

Papabravo

Joined Feb 24, 2006
17,240
So I took a quick look and the thing that stands out is the complete lack of meaningful comments. Without knowing something about what the inputs look like and what it is trying to do I'm at a loss for useful suggestions.
 

Thread Starter

camerart

Joined Feb 25, 2013
2,761
So I took a quick look and the thing that stands out is the complete lack of meaningful comments. Without knowing something about what the inputs look like and what it is trying to do I'm at a loss for useful suggestions.
Hi P,
Yes,it's a bit lacking in comments. I tend to comment when there is difficulty, but this worked ok previously, so not many comments.

In general thinking, when READing a series of registers from a chip e,g,(AK8963C), where could BITs be lost.
The meaningful BITs in this case shoud be READ in BURST mode, I'm re-checking this at the moment.
Cheers, C.
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
2,761
Hi P,
I started using the AK8963C 2 1/2 years ago, here is my 'break out' board. As you can see there is a DRDY PIN.

Looking at the D/S I am reminded that this could be the key? At the moment, I'm using the buffer full BIT on the PIC, but not watching the DRDY on the CHIP.

Happily, I made the PCB, DRDY ready.

I've now got to figure out how to READ the DRDY PIN in the program.
C
 

Attachments

ericgibbs

Joined Jan 29, 2010
14,130
hi C,
Why are you reading the Comp regs with 19 Clock pulses.?
'READ COMPASS XYZ REGISTER
Proc read_compass()
Toggle yled
For i = 0 To 18 '5 'READ ALL (except RSV. Is TS1 and 2 OK?)
compss_cs = 0 'CHIP SELECT COMPASS ON
rd_adr = 0x80 + i '00=WRITE 80=READ
WaitUs 1
SSPBUF = rd_adr
While Not SSPSTAT.BF
Wend
WaitUs 1
SSPBUF = 0 'Dummy BYTE
While Not SSPSTAT.BF
Wend

The compass d/s shows the two possible clocking options.
ESP_ 560 Jul. 06 11.54.png
 

Thread Starter

camerart

Joined Feb 25, 2013
2,761
hi C,
Why are you reading the Comp regs with 19 Clock pulses.?
'READ COMPASS XYZ REGISTER
Proc read_compass()
Toggle yled
For i = 0 To 18 '5 'READ ALL (except RSV. Is TS1 and 2 OK?)
compss_cs = 0 'CHIP SELECT COMPASS ON
rd_adr = 0x80 + i '00=WRITE 80=READ
WaitUs 1
SSPBUF = rd_adr
While Not SSPSTAT.BF
Wend
WaitUs 1
SSPBUF = 0 'Dummy BYTE
While Not SSPSTAT.BF
Wend

The compass d/s shows the two possible clocking options.
View attachment 242798
Hi E,
I haven't forgotten that you mentioned this previously, and am investigating this and other things.

I have to also check SINGLE and MULITIPLE READ in the D/S. I think how I've been doing it isn't quite correct.

I think I set to For i = 0 To 18 to make sure I READ all of the necessary Register, but perhaps if I did it once to check, then only READ 0x03-0x08 for running?
C
 

Thread Starter

camerart

Joined Feb 25, 2013
2,761
hi C,
Who wrote that Function routine.?:)

E
Hi E,
Which one?

Do you mean this:
C
Code:
For i = 0 To 18  '5  'READ ALL (except RSV.  Is TS1 and 2 OK?)
        compss_cs = 0  'CHIP SELECT COMPASS ON
            rd_adr = 0x80 + i  '00=WRITE 80=READ
            WaitUs 1
            SSPBUF = rd_adr
            While Not SSPSTAT.BF
            Wend
            WaitUs 1
            SSPBUF = 0  'Dummy BYTE
            While Not SSPSTAT.BF
            Wend
            periph_rd = SSPBUF
            b(i) = periph_rd
        compss_cs = 1  'CHIP SELECT COMPASS OFF
    Next i
 

ericgibbs

Joined Jan 29, 2010
14,130
hi,
OK,
But when using 19 Clk pulses you are ignoring the d/s
ESP_ 561 Jul. 06 12.21.png
Also why are you switching the Comp CS line Hi/Lo for every Clk pulse.?

For the Comp Drdy pin, just read the Com Rdy pin and IF ready then go get the Function data.

E
 

Thread Starter

camerart

Joined Feb 25, 2013
2,761
hi,
OK,
But when using 19 Clk pulses you are ignoring the d/s
View attachment 242799
Also why are you switching the Comp CS line Hi/Lo for every Clk pulse.?

For the Comp Drdy pin, just read the Com Rdy pin and IF ready then go get the Function data.

E
Hi E,
This is one of my tests, as mentioned bottom line #13

The test I'm on at the moment, isn't 'seeing' DRDY.

I'm pretty sure switching compss_cs HI/LO was found to work by many tests. I can re-look at this, along with all of the other tests.
C.
 

ericgibbs

Joined Jan 29, 2010
14,130
The test I'm on at the moment, isn't 'seeing' DRDY.
Hi,

Which pin of the MCU is connected to the Rdy pin of the compass.?
and how are you reading it in the MCU.?

E
ESP_ 562 Jul. 06 13.47.png
 

Thread Starter

camerart

Joined Feb 25, 2013
2,761
hi,
This a copy of a SPI basic program I sent you over 2 years ago.
Check thru it.

E
Hi E,
Remember your aversion to me posting my programs, and remember converting your program to suit 'live' testing with my PCB, and also remember you telling me off for changing it. It's not easy :)
C
 

Thread Starter

camerart

Joined Feb 25, 2013
2,761
The test I'm on at the moment, isn't 'seeing' DRDY.
Hi,

Which pin of the MCU is connected to the Rdy pin of the compass.?
and how are you reading it in the MCU.?

E
View attachment 242803
Hi E,
I have a digital analyser connected to the compass PINs. It is showing all of the READ/WRITE but not DRDY at PIN39.

NOTE: This is PCB7, my tests are on a similar but different PCB5(Deleted so I don't mix up)
EDITED

C
 

Attachments

Last edited:
Top