fifo read was stuffed up
reg = FIFO_DATA
i2cread sda,scl,ADDR,reg,[buffer[index+2],buffer[index+1],buffer[index+0],buffer[index+5],buffer[index+4],buffer[index+3]]
the fifo print out is incorrect also , not yet solved
fifo read was stuffed up
reg = FIFO_DATA
i2cread sda,scl,ADDR,reg,[buffer[index+2],buffer[index+1],buffer[index+0],buffer[index+5],buffer[index+4],buffer[index+3]]
the fifo print out is incorrect also , not yet solved
Warning I'm not a teacher
most of the drivers i've seen over the net are using the following...my code , you should know i have no idea :-
1, what led pwr to use
2, what led pwidth to use
3, what sample rate to use
4, what sample resolution to use
5, if there are any fifo overflows and if it matters much
6, what led the readings represents
7, how to interpret the data
8, how much data to collect [i assume at least 2 seconds worth]
1, what led pwr to use : 0x1F about 6.2 mA
2, what led pwidth to use : 411 which is 18 ADC BIT RESOLUTION based on the manual.
3, what sample rate to use : sample rate per second 100
a configuration should also include: sampleAverage = 8
4, what sample resolution to use :
5, if there are any fifo overflows and if it matters much.
6, what led the readings represents. I will search and find out.
7, how to interpret the data....
8, how much data to collect [i assume at least 2 seconds worth]
this looks like something, probably needs a lpf and sum of the squares function to remove dc drift
Code:'****************************************************************'* Name : MAX30102 FOR PIC 18 DEMO * '* Author : Richard * '* Notice : * '* : * '* Date : 9/1/2022 * '* Version : 1.0 * '* Notes : MAX30102 * '* :18f26k22 @64Mhz * '**************************************************************** #CONFIG ; The PBP configuration for the PIC18F26K22 is: CONFIG FOSC = INTIO67 CONFIG PLLCFG = OFF ;Oscillator multiplied by 4 CONFIG PRICLKEN = ON ;Primary clock enabled CONFIG FCMEN = OFF ;Fail-Safe Clock Monitor disabled CONFIG IESO = OFF ;Oscillator Switchover mode disabled CONFIG BOREN = SBORDIS ; Brown-out Reset enabled in hardware only (SBOREN is disabled) CONFIG WDTEN = ON ; WDT is always enabled. SWDTEN bit has no effect ;| CONFIG WDTPS = 32768 ; 1:32768 ---> HERE enable the watchdog timer with a 1:32768 postscale;| CONFIG PWRTEN = ON CONFIG HFOFST = ON ; HFINTOSC output and ready status are not delayed by the oscillator stable status CONFIG MCLRE = EXTMCLR ; MCLR pin enabled, RE3 input pin disabled CONFIG LVP = OFF ; Single-Supply ICSP disabled CONFIG XINST = OFF ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode) CONFIG DEBUG = OFF ; Disabled CONFIG CP0 = OFF ; Block 0 (000800-003FFFh) not code-protected CONFIG CP1 = OFF ; Block 1 (004000-007FFFh) not code-protected CONFIG CP2 = OFF ; Block 2 (008000-00BFFFh) not code-protected CONFIG CP3 = OFF ; Block 3 (00C000-00FFFFh) not code-protected CONFIG CPB = OFF ; Boot block (000000-0007FFh) not code-protected CONFIG CPD = OFF ; Data EEPROM not code-protected CONFIG WRT0 = OFF ; Block 0 (000800-003FFFh) not write-protected CONFIG WRT1 = OFF ; Block 1 (004000-007FFFh) not write-protected CONFIG WRT2 = OFF ; Block 2 (008000-00BFFFh) not write-protected CONFIG WRT3 = OFF ; Block 3 (00C000-00FFFFh) not write-protected CONFIG WRTC = OFF ; Configuration registers (300000-3000FFh) not write-protected CONFIG WRTB = OFF ; Boot Block (000000-0007FFh) not write-protected CONFIG WRTD = OFF ; Data EEPROM not write-protected CONFIG EBTR0 = OFF ; Block 0 (000800-003FFFh) not protected from table reads executed in other blocks CONFIG EBTR1 = OFF ; Block 1 (004000-007FFFh) not protected from table reads executed in other blocks CONFIG EBTR2 = OFF ; Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks CONFIG EBTR3 = OFF ; Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks CONFIG EBTRB = OFF ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks #ENDCONFIG 'define I2C_SLOW 1 define OSC 64 OSCCON = %01110000 ; 16Mhz OSCTUNE.6 = 1 ; Enable 4x PLL while ! osccon2.7 :WEND ; to make sure the pll has stabilised before you run any other code TRISC = %11011000 ANSELC=0 #DEFINE DEBUGING 1 #IFNDEF DEBUGING DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1 DEFINE HSER_CLROERR 1 ' Clear overflow automatically DEFINE HSER_SPBRG 160 ' 38400 Baud @ 64MHz, -0.08% SPBRGH = 1 BAUDCON.3 = 1 ' Enable 16 bit baudrate generator #ELSE DEFINE DEBUG_REG PORTB DEFINE DEBUG_BIT 7 DEFINE DEBUG_BAUD 9600 DEFINE DEBUG_MODE 0 ANSELB=0 LATB.7=1 #ENDIF SDA var portc.4 ' DATA PIN SCL VAR portc.3 ' CLOCK PIN Timeout cON 2000 reg var BYTE fifo var byte[6] addr var byte REVISION var byte PARTID var byte buffer var byte[1152] ptr var byte btr var byte index var word result var word ext @result = _fifo ;----------------------- REGISTER ------------------------- REG_TEMP_INT con $1F REG_TEMP_FRAC con $20 REG_TEMP_CONFIG con $21 REG_PART_REVISION con $FE REG_MODE con $09 REG_SPO2_CONFIG con $0A ;SPO2_ADC_RGE[6:5]SPO2_SR[4:2]LED_PW[1:0] REG_LED1_PA con $0C REG_LED2_PA con $0D FIFO_WR_PTR con $04 ;FIFO_WR_PTR[4:0] FIFO_RD_PTR con $06 FIFO_DATA con $07 FIFO_CONFIG con $08 ;FIFO_A_FULL[3:0] SMP_AVE[7:5] STATUS1 con 0 ;A_FULL[7] ' -----------------------------------------------------------------------------| #IFDEF DEBUGING PAUSE 2000 DEBUG 13,10, "READY" #ENDIF ADDR = $ae ; addr is 0x57 << 1 reg = REG_PART_REVISION i2cread SDA,scl,ADDR,reg,[REVISION,PARTID] reg = REG_MODE i2cwrite SDA,scl,ADDR,reg,[3] reg = REG_SPO2_CONFIG i2cwrite SDA,scl,ADDR,reg,[$20] reg = REG_LED2_PA i2cwrite SDA,scl,ADDR,reg,[9] reg = REG_LED1_PA i2cwrite SDA,scl,ADDR,reg,[9] reg = FIFO_CONFIG i2cwrite SDA,scl,ADDR,reg,[16] #IFNDEF DEBUGING HSEROUT [$73,$03,$04,$11,$ff,$ff,"PART ID: 0X",hex PARTID,"/0X", hex REVISION,$00] Hserin timeout,error,[wait(6)] #ELSE DEBUG 13,10, "PART ID: 0X",hex PARTID,"/0X",hex REVISION #ENDIF '******************************************************************************** start: reg= REG_TEMP_CONFIG i2cwrite SDA,scl,ADDR,reg,[1] reg= REG_TEMP_INT i2cread sda,scl,ADDR,reg,[fifo[0],fifo[1]] #IFNDEF DEBUGING HSEROUT [$73,$05,$0A,$11,$07,$E0,"TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6),$00] Hserin timeout,error,[wait(6)] #ELSE DEBUG 13,10, "TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6) #ENDIF GOSUB AQUIRE pause 5000 goto start aquire: reg= FIFO_WR_PTR i2cwrite SDA,scl,ADDR,reg,[0] reg= FIFO_RD_PTR i2cwrite SDA,scl,ADDR,reg,[0] pause 200 FOR index = 0 TO 1151 STEP 0 btr = 0 reg = STATUS1 WHILE btr&$80 = 0 i2cread sda,scl,ADDR,reg,[btr] WEND reg = FIFO_RD_PTR i2cread SDA,scl,ADDR,reg,[btr] btr = (btr - ptr) & 31 WHILE btr reg = FIFO_DATA i2cread sda,scl,ADDR,reg,[buffer[index + 2],buffer[index + 1],buffer[index + 0],buffer[index + 5],buffer[index + 4],buffer[index + 3]] index = index + 6 btr = btr - 1 ptr = (Ptr + 1) & 31 WEND pause 200 DEBUG "." NEXT FOR index = 0 TO 1151 STEP 0 for ptr = 0 to 2 fifo[ptr] = buffer[index + ptr] next DEBUG 13,10;, hex2 fifo[2] , hex2 fifo[1], hex2 fifo[0] ' asm ;ROTATE READING TO GET SUFFICIENT RESOLOUTION INTO UPPER WORD ' banksel _fifo ' bcf STATUS,C ' RRCF _fifo + 2 ,f ' RRCF _fifo + 1 ,f ' RRCF _fifo ,f ' bcf STATUS,C ' RRCF _fifo + 2 ,f ' RRCF _fifo + 1 ,f ' RRCF _fifo ,f ' banksel 0 ' endasm DEBUG 9,HEX4 result index = index + 3 ' DEBUG 13,10, hex2 buffer[index+2],hex2 buffer[index+1],hex2 buffer[index],9 ,HEX4 result ' DEBUG 9, hex2 fifo[2] , hex2 fifo[1], hex2 fifo[0] for ptr = 0 to 2 fifo[ptr] = buffer[index + ptr] next ' DEBUG 9, hex2 fifo[2] , hex2 fifo[1], hex2 fifo[0] ' asm ;ROTATE READING TO GET SUFFICIENT RESOLOUTION INTO UPPER WORD ' banksel _fifo ' bcf STATUS,C ' RRCF _fifo +2 ,f ' RRCF _fifo +1 ,f ' RRCF _fifo ,f ' bcf STATUS,C ' RRCF _fifo +2 ,f ' RRCF _fifo +1 ,f ' RRCF _fifo ,f ' banksel 0 ' endasm DEBUG 9,HEX4 result index = index + 3 NEXT RETURN
Warning I'm not a teacher
its alive i think
gives me a 63 rpm
Warning I'm not a teacher
Low pass filter in excel
![]()
makes peak detection look possible
Code:'****************************************************************'* Name : MAX30102 FOR PIC 18 DEMO * '* Author : Richard * '* Notice : * '* : * '* Date : 9/1/2022 * '* Version : 1.0 * '* Notes : MAX30102 * '* :18f26k22 @64Mhz * '**************************************************************** #CONFIG ; The PBP configuration for the PIC18F26K22 is: CONFIG FOSC = INTIO67 CONFIG PLLCFG = OFF ;Oscillator multiplied by 4 CONFIG PRICLKEN = ON ;Primary clock enabled CONFIG FCMEN = OFF ;Fail-Safe Clock Monitor disabled CONFIG IESO = OFF ;Oscillator Switchover mode disabled CONFIG BOREN = SBORDIS ; Brown-out Reset enabled in hardware only (SBOREN is disabled) CONFIG WDTEN = ON ; WDT is always enabled. SWDTEN bit has no effect ;| CONFIG WDTPS = 32768 ; 1:32768 ---> HERE enable the watchdog timer with a 1:32768 postscale;| CONFIG PWRTEN = ON CONFIG HFOFST = ON ; HFINTOSC output and ready status are not delayed by the oscillator stable status CONFIG MCLRE = EXTMCLR ; MCLR pin enabled, RE3 input pin disabled CONFIG LVP = OFF ; Single-Supply ICSP disabled CONFIG XINST = OFF ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode) CONFIG DEBUG = OFF ; Disabled CONFIG CP0 = OFF ; Block 0 (000800-003FFFh) not code-protected CONFIG CP1 = OFF ; Block 1 (004000-007FFFh) not code-protected CONFIG CP2 = OFF ; Block 2 (008000-00BFFFh) not code-protected CONFIG CP3 = OFF ; Block 3 (00C000-00FFFFh) not code-protected CONFIG CPB = OFF ; Boot block (000000-0007FFh) not code-protected CONFIG CPD = OFF ; Data EEPROM not code-protected CONFIG WRT0 = OFF ; Block 0 (000800-003FFFh) not write-protected CONFIG WRT1 = OFF ; Block 1 (004000-007FFFh) not write-protected CONFIG WRT2 = OFF ; Block 2 (008000-00BFFFh) not write-protected CONFIG WRT3 = OFF ; Block 3 (00C000-00FFFFh) not write-protected CONFIG WRTC = OFF ; Configuration registers (300000-3000FFh) not write-protected CONFIG WRTB = OFF ; Boot Block (000000-0007FFh) not write-protected CONFIG WRTD = OFF ; Data EEPROM not write-protected CONFIG EBTR0 = OFF ; Block 0 (000800-003FFFh) not protected from table reads executed in other blocks CONFIG EBTR1 = OFF ; Block 1 (004000-007FFFh) not protected from table reads executed in other blocks CONFIG EBTR2 = OFF ; Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks CONFIG EBTR3 = OFF ; Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks CONFIG EBTRB = OFF ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks #ENDCONFIG 'define I2C_SLOW 1 define OSC 64 OSCCON = %01110000 ; 16Mhz OSCTUNE.6 = 1 ; Enable 4x PLL while ! osccon2.7 :WEND ; to make sure the pll has stabilised before you run any other code TRISC = %11011000 ANSELC=0 #DEFINE DEBUGING 1 #IFNDEF DEBUGING DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1 DEFINE HSER_CLROERR 1 ' Clear overflow automatically DEFINE HSER_SPBRG 160 ' 38400 Baud @ 64MHz, -0.08% SPBRGH = 1 BAUDCON.3 = 1 ' Enable 16 bit baudrate generator #ELSE DEFINE DEBUG_REG PORTB DEFINE DEBUG_BIT 7 DEFINE DEBUG_BAUD 9600 DEFINE DEBUG_MODE 0 ANSELB=0 LATB.7=1 #ENDIF SDA var portc.4 ' DATA PIN SCL VAR portc.3 ' CLOCK PIN Timeout cON 2000 reg var BYTE fifo var byte[6] addr var byte REVISION var byte PARTID var byte buffer var byte[1152] ptr var byte btr var byte index var word result var word ext @result = _fifo ;----------------------- REGISTER ------------------------- REG_TEMP_INT con $1F REG_TEMP_FRAC con $20 REG_TEMP_CONFIG con $21 REG_PART_REVISION con $FE REG_MODE con $09 REG_SPO2_CONFIG con $0A ;SPO2_ADC_RGE[6:5]SPO2_SR[4:2]LED_PW[1:0] REG_LED1_PA con $0C REG_LED2_PA con $0D FIFO_WR_PTR con $04 ;FIFO_WR_PTR[4:0] FIFO_RD_PTR con $06 FIFO_DATA con $07 FIFO_CONFIG con $08 ;FIFO_A_FULL[3:0] SMP_AVE[7:5] OVF_COUNTER con $05 STATUS1 con 0 ;A_FULL[7] INTERRUPT_EN con 2 ' -----------------------------------------------------------------------------| #IFDEF DEBUGING PAUSE 2000 DEBUG 13,10, "READY" #ENDIF ADDR = $ae ; addr is 0x57 << 1 reg = REG_PART_REVISION i2cread SDA,scl,ADDR,reg,[REVISION,PARTID] reg = REG_MODE i2cwrite SDA,scl,ADDR,reg,[3] reg = REG_SPO2_CONFIG i2cwrite SDA,scl,ADDR,reg,[$20] reg = REG_LED2_PA i2cwrite SDA,scl,ADDR,reg,[10] reg = REG_LED1_PA i2cwrite SDA,scl,ADDR,reg,[10] reg = FIFO_CONFIG i2cwrite SDA,scl,ADDR,reg,[16] reg = INTERRUPT_EN i2cwrite SDA,scl,ADDR,reg,[$E0] #IFNDEF DEBUGING HSEROUT [$73,$03,$04,$11,$ff,$ff,"PART ID: 0X",hex PARTID,"/0X", hex REVISION,$00] Hserin timeout,error,[wait(6)] #ELSE DEBUG 13,10, "PART ID: 0X",hex PARTID,"/0X",hex REVISION #ENDIF '******************************************************************************** start: reg= REG_TEMP_CONFIG i2cwrite SDA,scl,ADDR,reg,[1] reg= REG_TEMP_INT i2cread sda,scl,ADDR,reg,[fifo[0],fifo[1]] #IFNDEF DEBUGING HSEROUT [$73,$05,$0A,$11,$07,$E0,"TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6),$00] Hserin timeout,error,[wait(6)] #ELSE DEBUG 13,10, "TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6) #ENDIF GOSUB AQUIRE pause 5000 goto start aquire: reg= FIFO_WR_PTR i2cwrite SDA,scl,ADDR,reg,[0] reg= FIFO_RD_PTR i2cwrite SDA,scl,ADDR,reg,[0] reg = OVF_COUNTER i2cwrite sda,scl,ADDR,reg,[0] FOR index = 0 TO 1151 STEP 0 btr = 0 reg = STATUS1 WHILE (btr&192) = 0 PAUSE 10 i2cread sda,scl,ADDR,reg,[btr] DEBUG "Y" ,DEC btr WEND ' reg = FIFO_WR_PTR i2cread SDA,scl,ADDR,reg,[Ptr] reg = FIFO_RD_PTR i2cread SDA,scl,ADDR,reg,[btr] btr = (ptr - btr) & 31 DEBUG "Z" ,DEC btr WHILE btr reg = FIFO_DATA i2cread sda,scl,ADDR,reg,[buffer[index + 2],buffer[index + 1],buffer[index + 0],buffer[index + 5],buffer[index + 4],buffer[index + 3]] index = index + 6 btr = btr - 1 WEND NEXT reg = OVF_COUNTER i2cread sda,scl,ADDR,reg,[reg ] DEBUG 13,10,"OF ",DEC reg FOR index = 0 TO 1151 STEP 0 for ptr = 0 to 2 fifo[ptr] = buffer[index + ptr] next DEBUG 13,10;, hex2 fifo[2] , hex2 fifo[1], hex2 fifo[0] asm ;ROTATE READING TO GET SUFFICIENT RESOLOUTION INTO UPPER WORD banksel _fifo bcf STATUS,C RRCF _fifo + 2 ,f RRCF _fifo + 1 ,f RRCF _fifo ,f bcf STATUS,C RRCF _fifo + 2 ,f RRCF _fifo + 1 ,f RRCF _fifo ,f banksel 0 endasm DEBUG 9,HEX4 result index = index + 3 ' DEBUG 13,10, hex2 buffer[index+2],hex2 buffer[index+1],hex2 buffer[index],9 ,HEX4 result ' DEBUG 9, hex2 fifo[2] , hex2 fifo[1], hex2 fifo[0] for ptr = 0 to 2 fifo[ptr] = buffer[index + ptr] next ' DEBUG 9, hex2 fifo[2] , hex2 fifo[1], hex2 fifo[0] asm ;ROTATE READING TO GET SUFFICIENT RESOLOUTION INTO UPPER WORD banksel _fifo bcf STATUS,C RRCF _fifo +2 ,f RRCF _fifo +1 ,f RRCF _fifo ,f bcf STATUS,C RRCF _fifo +2 ,f RRCF _fifo +1 ,f RRCF _fifo ,f banksel 0 endasm DEBUG 9,HEX4 result index = index + 3 NEXT RETURN
Warning I'm not a teacher
Richard,
looking at your code,i'm learning lots of things.
All the registers you have are constants. And that is what i've thought also in the beggining.
But in the manual it says that we never use constants for the I2C command.Code:;----------------------- REGISTER ------------------------- REG_TEMP_INT con $1F REG_TEMP_FRAC con $20 REG_TEMP_CONFIG con $21 REG_PART_REVISION con $FE REG_MODE con $09 REG_SPO2_CONFIG con $0A ;SPO2_ADC_RGE[6:5]SPO2_SR[4:2]LED_PW[1:0] REG_LED1_PA con $0C REG_LED2_PA con $0D FIFO_WR_PTR con $04 ;FIFO_WR_PTR[4:0] FIFO_RD_PTR con $06 FIFO_DATA con $07 FIFO_CONFIG con $08 ;FIFO_A_FULL[3:0] SMP_AVE[7:5] STATUS1 con 0 ;A_FULL[7] ' -----------------------------------------------------------------------------|
What i have realised is that you refer to the
everytime you need to asign a constant value to it. Is that right? with that way we alter the restriction of using constants. (or am i wrong?)Code:reg var byte
Sencod question.
I see you are always using the Write Address:
even if you want to read from:Code:ADDR = $ae ; addr is 0x57 << 1 reg = REG_PART_REVISION i2cread SDA,scl,ADDR,reg,[REVISION,PARTID] reg = REG_MODE i2cwrite SDA,scl,ADDR,reg,[3] reg = REG_SPO2_CONFIG i2cwrite SDA,scl,ADDR,reg,[$20] reg = REG_LED2_PA i2cwrite SDA,scl,ADDR,reg,[9] reg = REG_LED1_PA i2cwrite SDA,scl,ADDR,reg,[9] reg = FIFO_CONFIG i2cwrite SDA,scl,ADDR,reg,[16]
im confused here. When do we use the write address and when do we use the read address!!!Code:reg= REG_TEMP_INT i2cread sda,scl,ADDR,reg,[fifo[0],fifo[1]]
But in the manual it says that we never use constants for the I2C command.
What i have realised is that you refer to the
everytime you need to asign a constant value to it. Is that right? with that way we alter the restriction of using constants. (or am i wrong?)Code:reg var byte
in pbp constants are 16 bit, they are fine in i2c when a 16 bit value is appropriate and the endianness matches
if you use a var there is never any doubt, you get what you asked for but the endianness must match
there is no such thing as write address or read address in pbp there is only the addressim confused here. When do we use the write address and when do we use the read address!!!
Warning I'm not a teacher
there is an adress of 7 bits....then PBP is taking care for the Read or Write bit.there is no such thing as write address or read address in pbp there is only the address
The following is from the manual of the MAX30102.
But in the program under the registers we are using the AE which is related to write address. Isnt it?
Code:ADDR = $ae ; addr is 0x57 << 1
you are trying to create a problem that does not exist there is no such thing as write address or read address in pbp there is only the addressBut in the program under the registers we are using the AE which is related to write address. Isnt it?
a pbp i2c address is the 7bit manufacturer's address left shifted 1 bit, the only variation is for crappy ancient eeproms where the "page"
address forms part of the address[control] , but bit0 is still under pbp control regardless
you don't quibble the hserout command adding start and stop bits to your serial transmission or even calculating the parity and inserting it also
![]()
why should the i2c "high level" commands not be able to set the r/w bit as required, after all that's why you use pbp. it stops you needing to dig into the bowels of i2c transactions
the manual
lets not hear any more of this nonsense
Last edited by richard; - 13th January 2022 at 00:57.
Warning I'm not a teacher
Bookmarks