|
|
View previous topic :: View next topic |
Author |
Message |
-Terppa-
Joined: 08 Jan 2018 Posts: 59 Location: Finland
|
DSPic33ep512mc204 and max30001 |
Posted: Fri Jun 09, 2023 7:09 am |
|
|
Hello!
I'll try to read max30001 info register (0x0f) but i cannot get any data out..
only (0xff)
There is thousands of way what i try but there is one of them.
SPI setup:
Code: |
#ifdef USE_SPI1
#warning SPI1 is hardwired SDI1=a9, SDO1=a4, SCK1OUT=c3
#use SPI(MASTER, SPI1, MODE=0, BITS=8, MSB_FIRST, stream=SPIBUS1, FORCE_HW)
#endif
|
Test read INFO register from MAX30001
Code: |
//MAX30001 read iNFO (0 1 0 1 x x x x) REVid
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int1 max30001ReadInfo(void)
{
#define MAXINFO 0x0f
unsigned int8 readBuff[4];
max30001RegRead(MAXINFO,readBuff);
if((readBuff[0]&0xf0)==0x50)
{
fprintf(MA30001SERIALBUS,"\n\rMAX30001 Detected. Rev ID:");
fprintf(MA30001SERIALBUS,"0x%x, %u",(readBuff[0]&0xf0),max30001ok);
max30001ok=TRUE;
return 1;
}
else
{
max30001ok=FALSE;
fprintf(MA30001SERIALBUS,"\n\rMAX30001 not detected.. 0x%x, %u",(readBuff[0]&0xf0),max30001ok);
return 0;
}
return 0;
}
|
Read register
Code: |
//MAX30001 register read
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void max30001RegRead(unsigned int8 Reg_address, unsigned int8 *buff)
{
unsigned int8 spiTxBuff;
//low(spiCS);
//delay_ms(10);
spiTxBuff=(Reg_address<<1)|RREG;
SPI_XFER_(spiTxBuff);
for(unsigned int8 ii=0;ii<3;ii++)
buff[ii]=read_ext_spi8(0xff);
//delay_ms(10);
//high(spiCS);
fprintf(MA30001SERIALBUS,"\n\rThis is what we have in buffer..");
fprintf(MA30001SERIALBUS,"\n\r0x%x",buff[0]);
fprintf(MA30001SERIALBUS,"\n\r0x%x",buff[1]);
fprintf(MA30001SERIALBUS,"\n\r0x%x",buff[2]);
}
|
SPI read and write
Code: |
//----------------------------------------------
void write_ext_spi8(int16 address,int8 data)
{
output_low(spiCS);
delay_us(SPICSDELAY);
//SPI_XFER_(0x02); //sends write command
SPI_XFER_(make8(address,1)); //sends MS Byte of address
SPI_XFER_(make8(address,0)); //sends LS Byte of address
SPI_XFER_(data); //writes the byte of data
output_high(spiCS);
delay_us(SPICSDELAY);
}
//----------------------------------------------
int8 read_ext_spi8(int16 address)
{
int8 data;
output_low(spiCS);
delay_us(SPICSDELAY);
//SPI_XFER_(0x03); //sends read command
SPI_XFER_(make8(address,1)); //sends MS Byte of address
SPI_XFER_(make8(address,0)); //sends LS Byte of address
data=SPI_READ_(); //reads the byte of data
output_high(spiCS);
delay_us(SPICSDELAY);
return(data);
}
|
Something is wrong but can you see what is it?
Thank you for your support.
Compiler PCWHD 5.112 and MPLAB IDE 8.92 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Fri Jun 09, 2023 7:32 am |
|
|
1st thought... what SPI 'mode' is the MAX30001 ? I downloaded the datasheet and it's sad that you have to decode the diagram to figure this out (I didn't...silly me expected it in writing...) yes, the older I get, the crankier I get....
I did read something about 32 bits, so I'm assuming you have to send 4 BYTES to get the device to work ??
You should be able to get 'sample code' from the maker, or google...that should help even if in another dialect of 'C'. |
|
|
-Terppa-
Joined: 08 Jan 2018 Posts: 59 Location: Finland
|
|
Posted: Fri Jun 09, 2023 7:52 am |
|
|
I believe device speed is 1000000 and i think you are right about that 4-bytes reading..
Info register content should be look like this:
(0 1 0 1 x x x x) REVid
should i send info address(0x0f) and read back 24bits or 32bits?
and how to actually do this? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19495
|
|
Posted: Fri Jun 09, 2023 10:37 am |
|
|
The SPI mode is 'worrying'. If you look at the timing diagram, it expects to
read data from you on the rising edge of the clock, but expects you to read
it's data on the falling edge!..... However it does show the last bit being
generated ahead of the rising edge, so suggests it wants mode 0.
It states in the datasheet that it supports modes 0 or 3, suggesting the
diagram has a bit of artistic license on when the stuff is clocked.
The basic communication, is that you clock it 4 bytes. A 7 bit address
with a Read/Write bit and then 24bits of data. You get back 24bits of
reply, if R is 1.. You need to operate the CSB bit between each four byte
packet. On the read operations, what you write in the last three bytes
is ignored. The actual write occurs when the last bit is clocked in.
You can also use a 24bit multi transfer mode, sending a single address/R
byte, then clocking three bytes, and repeating clocking three more bytes
each time.
To read register 0xF, you need to start with CSB low. Then pulse it high
for at least 20nSec. Drop it again, and start the SPI transfer.
You send 0xF shifted left one bit, and or'ed with the Read bit (1). So
you would want 0x1F.
I see you do this.
The key though is the clocking of CSB. |
|
|
-Terppa-
Joined: 08 Jan 2018 Posts: 59 Location: Finland
|
|
Posted: Fri Jun 16, 2023 1:28 am |
|
|
I cannot use reference point in Info register.. Because:
Code: |
Note: Due to internal initialization procedures,
this command will not read-back valid data if it is the first command executed following either a power-cycle event, or a SW_RST event.
|
It is hard to know when my Rd or Wr- functions works how they should be.
I'm stuck again.
I'll found this:
Code: |
void MAX30001::_max30001RegRead(uint8_t Reg_address, uint8_t *buff)
{
uint8_t spiTxBuff;
SPI.beginTransaction(SPISettings(MAX30001_SPI_SPEED, MSBFIRST, SPI_MODE0));
digitalWrite(_cs_pin, LOW);
spiTxBuff = (Reg_address << 1) | RREG;
SPI.transfer(spiTxBuff); // Send register location
for (int i = 0; i < 3; i++)
{
buff[i] = SPI.transfer(0xff);
}
digitalWrite(_cs_pin, HIGH);
SPI.endTransaction();
}
|
I ignore line:
Code: |
SPI.beginTransaction(SPISettings(MAX30001_SPI_SPEED, MSBFIRST, SPI_MODE0));
|
Because i have:
Code: |
#use SPI(MASTER, SPI1, MODE=0, BITS=8, MSB_FIRST, stream=SPIBUS1, FORCE_HW)
|
Now this:
Code: |
SPI.transfer(spiTxBuff); // Send register location
|
Should i use this?
Code: |
SPI_XFER_(spiTxBuff);
|
or something like this?
Code: |
spi_transfer(bus, Wrdata, Rddata, 1);
|
Same thing in here:
Code: |
for (int i = 0; i < 3; i++)
{
buff[i] = SPI.transfer(0xff);
}
|
Can i write:
Code: |
spi_transfer_read(buff, 3);
|
In CCSC we dont need that?
Code: |
SPI.endTransaction();
|
If you can help I'm pleased.
Now it's time for coffee. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19495
|
|
Posted: Fri Jun 16, 2023 3:03 am |
|
|
Yes, you can use the info register. All you do, is send a FIFO_RST command,
then read the INFO register. FIFO_RST does not affect the chip in any way,
except to reset the FIFO buffers. The manufacturer recommends this as
the proceedure to verify communication is working. |
|
|
-Terppa-
Joined: 08 Jan 2018 Posts: 59 Location: Finland
|
|
Posted: Fri Jun 16, 2023 4:34 am |
|
|
Thank you for your help Mr.Ttelmah
Now, before when i asking "Info reg" i send FIFO reset. Now i get same answer back in info register all the time.
I check clock line in oscilloscope and pic sends 32 clk pulses.
Now read iNFO look's like this:
Code: |
//MAX30001 read iNFO (0 1 0 1 x x x x) REVid
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int1 max30001ReadInfo(void)
{
#define MAXINFO 0x0f
unsigned int8 readBuff[4];
//max30001RegWrite(FIFO_RST,0x000000);
//max30001RegRead(MAXINFO,0x000000);
max30001RegRead(MAXINFO,readBuff);
if((readBuff[0]&0xf0)==0x50)
{
fprintf(MA30001SERIALBUS,"\n\rMAX30001 Detected. Rev ID:");
fprintf(MA30001SERIALBUS,"0x%x, %u",(readBuff[0]&0xf0),max30001ok);
max30001ok=TRUE;
return 1;
}
else
{
max30001ok=FALSE;
fprintf(MA30001SERIALBUS,"\n\rMAX30001 not detected.. 0x%x, %u",(readBuff[0]&0xf0),max30001ok);
return 0;
}
return 0;
}
|
and read register:
Code: |
//MAX30001 register read
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void max30001RegRead(unsigned int8 Reg_address, unsigned int8 *buff)
{
//spi_transfer([stream], wData, rData, count)
//spi_transfer(wData, rData, 128);
unsigned int8 spiTxBuff=0;
low(spiCS);
delay_us(10);
spiTxBuff=(Reg_address<<1)|RREG;
//spi_transfer(EXTSPI1, spiTxBuff, buff, 1);
SPI_XFER_(spiTxBuff);
//fprintf(MA30001SERIALBUS,"\n\r\n\r(2)This is what we have in buffer..");
//fprintf(MA30001SERIALBUS,"\n\r0x%x",buff[0]);
for(unsigned int8 ii=0;ii<3;ii++)
SPI_XFER_(spiTxBuff);
// spi_transfer(EXTSPI1, 0xff, buff, ii);
// buff[ii]=SPI_READ_();
//spi_transfer_read(EXTSPI1,buff, 3);
delay_us(10);
high(spiCS);
fprintf(MA30001SERIALBUS,"\n\r\n\r(2)This is what we have in buffer..");
fprintf(MA30001SERIALBUS,"\n\r0x%x,[0]",buff[0]);
fprintf(MA30001SERIALBUS,"\n\r0x%x,[1]",buff[1]);
fprintf(MA30001SERIALBUS,"\n\r0x%x,[2]",buff[2]);
fprintf(MA30001SERIALBUS,"\n\r0x%x,[3]",buff[3]);
}
|
First sending "FIFOreset" and then "INFOreq" buffer content is:
buff[0]=0x0a
buff[1]=0x14
buff[2]=0x00
buff[3]=0x00 |
|
|
-Terppa-
Joined: 08 Jan 2018 Posts: 59 Location: Finland
|
|
Posted: Fri Jun 16, 2023 5:04 am |
|
|
Now i get "detected" status!
Maybe i little bit tired but i have MISO and MOSI crossed
Little change to "regread" function:
Code: |
void max30001RegRead(unsigned int8 Reg_address, unsigned int8 *buff)
{
unsigned int8 spiTxBuff=0;
low(spiCS);
delay_us(10);
spiTxBuff=(Reg_address<<1)|RREG;
SPI_XFER_(spiTxBuff);
spi_transfer_read(EXTSPI1,buff, 3);
delay_us(10);
high(spiCS);
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19495
|
|
Posted: Sat Jun 17, 2023 1:45 am |
|
|
Remembering this SDI->SDO and SDO->SDI, is a very old favourite...
I think it is one that everyone does once. Then it becomes 'flagged' in your
brain and much rarer.
At least you are now moving forwards. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Sat Jun 17, 2023 4:52 am |
|
|
progress ! always good, nice !!
sigh, took me years to figure out 'they' changed TXD and RXD pins on the good old RS-232 connectors on PCs when 9 pin became the 'standard'.
I'd love to know WHY that happened.....
yeah, I'm a dinosaur....still have computers with REAL comports in them. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|