DRDY PIC18F45K80 to QT1481
I also have a problem with DRDY. I need to include DRDY. The pins for DRDY are RD2 and RD5. They are both inputs.
Here is the information for DRDY.
DRDY Pin
DRDY is an open-drain output (in SPI mode) or bidirectional pin (in UART mode) with an internal 20 k – 50 k pullup
resistor.
Most communications failures are the result of failure to properly observe the DRDY timing.
Serial communications pacing is controlled by this pin. Use of DRDY is critical to successful communications with the
QT1481. In either UART or SPI mode, the host is permitted to perform a data transfer only when DRDY has returned
high. Additionally, in UART mode, the QT1481 delays responses to the host if DRDY is being held low by the host.
After each byte transfer, DRDY goes low after a short delay and remains low until the QT1481 is ready for another
transfer. A short delay occurs before DRDY is driven low because the QT1481 may otherwise be busy and requires
a finite time to respond.
DRDY may go low for a microsecond only. During the period from the end of one transfer until DRDY goes low and
back high again, the host should not perform another transfer. Therefore, before each byte transmission the host
should first check that DRDY is high again.
If the host wants to perform a byte transfer with the QT1481 it should behave as follows:
1. Wait at least 100 µs after the previous transfer (time S5 in Figure 3-2 on page 23: DRDY is guaranteed to go
low before this 100 µs expires).
2. Wait until DRDY is high (it may already be high).
3. Perform the next transfer with the QT1481.
In most cases it takes up to 3 ms for DRDY to return high again. However, this time is longer with some commands
or if the STS_DEBUG setup is enabled, as follows:0x01 (Setups load): <20 ms0x02 (Low Level Cal and Offset): <20 ms
Add 15 ms to the above times if the STS_DEBUG setup is enabled.
Other DRDY specifications:
Min time DRDY is low: 1 µs
Max time DRDY is low after reset: 100 ms
The timing diagram is this: 
How can implement that?
The code I have written with my friend is written here:
#include <xc.h>
#include "PIC.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//#include <pic18f45k80.h>
#define MSB 1
#define LSB 0
// SPI PIN CONFIGURATION
#define SCK_TRIS TRISCbits.TRISC3 = 0 ;
#define SDO_TRIS TRISCbits.TRISC5 = 0 ;
#define SDI_TRIS TRISCbits.TRISC4 = 1 ;
#define QTA_SS_TRIS TRISDbits.TRISD4 = 0 ;
#define QTB_SS_TRIS TRISEbits.TRISE2 = 0 ;
#define QTA_SS_LAT_LOW LATDbits.LATD4 = 0 ;
#define QTA_SS_LAT_HIGH LATDbits.LATD4 = 1 ;
#define QTB_SS_LAT_LOW LATEbits.LATE2 = 0 ;
#define QTB_SS_LAT_HIGH LATEbits.LATE2 = 1 ;
#define QTA_DRDY_TRIS TRISDbits.TRISD5 = 1 ;
#define QTB_DRDY_TRIS TRISDbits.TRISD2 = 1 ;
#define QTA_DRDY_LAT_LOW LATDbits.LATD5 = 0 ;
#define QTA_DRDY_LAT_HIGH LATDbits.LAT52 = 1 ;
#define QTB_DRDY_LAT_LOW LATDbits.LAT25 = 0 ;
#define QTB_DRDY_LAT_HIGH LATDbits.LATD2 = 1 ;
#define QTB_DRDY PORTDbits.RD2 ;
#define QTA_DRDY PORTDbits.RD5 ;
// FREQUENCY SELECT
#define _XTAL_FREQ 16000000
// PIN SETUP
void PIN_MANAGER_Initialize(void)
{
/**
LATx registers
*/
LATE = 0x00;
LATD = 0x00;
LATA = 0x00;
LATB = 0b00010000;
LATC = 0x00;
/**
TRISx registers
*/
TRISE = 0x00;
TRISA = 0x08;
TRISB = 0x01;
TRISC = 0b00010000;
TRISD = 0xEF;
PORTC = 0b00010010 ;
/**
ANSELx registers
*/
ANCON0 = 0x00;
ANCON1 = 0x00;
/**
WPUx registers
*/
WPUB = 0x00;
INTCON2bits.nRBPU = 1;
}
// SPI
void SPI_Initialize(void)
{
// SMP Middle; CKE Idle to Active;
SSPSTAT = 0b00000000;
// SSPEN enabled; WCOL no_collision; CKP Idle:High, Active:Low; SSPM FOSC/4; SSPOV no_overflow;
SSPCON1 = 0b00111010;
// SSPADD 0;
SSPADD = 0x00;
ADCON0 = 0 ;
ADCON1 = 0x0F ; //Makes all I/O digital
SCK_TRIS ;
SDO_TRIS ;
SDI_TRIS ;
QTA_SS_TRIS ;
QTB_SS_TRIS ;
QTA_DRDY_TRIS ;
QTB_DRDY_TRIS ;
}
signed char WriteSPI( unsigned char data_out )
{
unsigned char TempVar;
TempVar = SSPBUF; // Clears BF
PIR1bits.SSPIF = 0; // Clear interrupt flag
SSPCON1bits.WCOL = 0; //Clear any previous write collision
SSPBUF = data_out; // write byte to SSPBUF register
if ( SSPCON1 & 0x80 ) // test if write collision occurred
return ( -1 ); // if WCOL bit is set return negative #
else
while( !PIR1bits.SSPIF ); // wait until bus cycle complete
return ( 0 ); // if WCOL bit is not set return non-negative#
}
unsigned char ReadSPI( void )
{
unsigned char TempVar;
TempVar = SSPBUF; // Clear BF
PIR1bits.SSPIF = 0; // Clear interrupt flag
SSPBUF = 0x00; // initiate bus cycle
while(!PIR1bits.SSPIF); // wait until cycle complete
return ( SSPBUF ); // return with byte read
}
unsigned char DataRdySPI( void )
{
if ( SSPSTATbits.BF )
return ( +1 ); // data in SSPBUF register
else
return ( 0 ); // no data in SSPBUF register
}
// SOFTWARE EUART
void out_char(char character, char bit_order){
uint8_t i = 0;
RSOUT = 1 ; // MSB
__delay_ms(1);
RSOUT = 0 ; // START
__delay_us(100);
for (i = 8; i>0; --i){
if (bit_order){ // Bit order determines how you will put the bits, from left to right (MSB) or right to left (LSB)
RSOUT = (character & 0x80) ? 1:0; // in MSB you compare the left-most bit doing an AND with 0x80, and put 1 if true, 0 elsewhere.
character <<= 1; // Shift the character to the left, discrading the bit just sent
} else {
RSOUT = (character & 0x01); // in LSB you compare the right-most bit doing an AND with 0x01, and put 1 if true, 0 else.
character >>= 1; // Shift the character to the right, discrading the bit just sent
}
__delay_us(100);
}
RSOUT = 1 ; // STOP
}
void out_str(char * string, uint8_t len, char bit_order){
uint8_t i = 0;
for (i = 0; i< len; i++){
out_char(string[i], bit_order);
}
}
void SYSTEM_Initialize(void)
{
PIN_MANAGER_Initialize() ;
SPI_Initialize() ;
}
void main(void)
{
SYSTEM_Initialize() ;
while (1)
{
QTB_SS_LAT_LOW ; // Transmit data
char temp ;
WriteSPI(0x0F) ; // Send a byte
while(!DataRdySPI()) ; // wait for a data to arrive
temp = ReadSPI(); // Read a byte from the
QTB_SS_LAT_HIGH ; // Stop transmitting data
__delay_us(100) ;
}
}
c pic spi
add a comment |
I also have a problem with DRDY. I need to include DRDY. The pins for DRDY are RD2 and RD5. They are both inputs.
Here is the information for DRDY.
DRDY Pin
DRDY is an open-drain output (in SPI mode) or bidirectional pin (in UART mode) with an internal 20 k – 50 k pullup
resistor.
Most communications failures are the result of failure to properly observe the DRDY timing.
Serial communications pacing is controlled by this pin. Use of DRDY is critical to successful communications with the
QT1481. In either UART or SPI mode, the host is permitted to perform a data transfer only when DRDY has returned
high. Additionally, in UART mode, the QT1481 delays responses to the host if DRDY is being held low by the host.
After each byte transfer, DRDY goes low after a short delay and remains low until the QT1481 is ready for another
transfer. A short delay occurs before DRDY is driven low because the QT1481 may otherwise be busy and requires
a finite time to respond.
DRDY may go low for a microsecond only. During the period from the end of one transfer until DRDY goes low and
back high again, the host should not perform another transfer. Therefore, before each byte transmission the host
should first check that DRDY is high again.
If the host wants to perform a byte transfer with the QT1481 it should behave as follows:
1. Wait at least 100 µs after the previous transfer (time S5 in Figure 3-2 on page 23: DRDY is guaranteed to go
low before this 100 µs expires).
2. Wait until DRDY is high (it may already be high).
3. Perform the next transfer with the QT1481.
In most cases it takes up to 3 ms for DRDY to return high again. However, this time is longer with some commands
or if the STS_DEBUG setup is enabled, as follows:0x01 (Setups load): <20 ms0x02 (Low Level Cal and Offset): <20 ms
Add 15 ms to the above times if the STS_DEBUG setup is enabled.
Other DRDY specifications:
Min time DRDY is low: 1 µs
Max time DRDY is low after reset: 100 ms
The timing diagram is this: 
How can implement that?
The code I have written with my friend is written here:
#include <xc.h>
#include "PIC.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//#include <pic18f45k80.h>
#define MSB 1
#define LSB 0
// SPI PIN CONFIGURATION
#define SCK_TRIS TRISCbits.TRISC3 = 0 ;
#define SDO_TRIS TRISCbits.TRISC5 = 0 ;
#define SDI_TRIS TRISCbits.TRISC4 = 1 ;
#define QTA_SS_TRIS TRISDbits.TRISD4 = 0 ;
#define QTB_SS_TRIS TRISEbits.TRISE2 = 0 ;
#define QTA_SS_LAT_LOW LATDbits.LATD4 = 0 ;
#define QTA_SS_LAT_HIGH LATDbits.LATD4 = 1 ;
#define QTB_SS_LAT_LOW LATEbits.LATE2 = 0 ;
#define QTB_SS_LAT_HIGH LATEbits.LATE2 = 1 ;
#define QTA_DRDY_TRIS TRISDbits.TRISD5 = 1 ;
#define QTB_DRDY_TRIS TRISDbits.TRISD2 = 1 ;
#define QTA_DRDY_LAT_LOW LATDbits.LATD5 = 0 ;
#define QTA_DRDY_LAT_HIGH LATDbits.LAT52 = 1 ;
#define QTB_DRDY_LAT_LOW LATDbits.LAT25 = 0 ;
#define QTB_DRDY_LAT_HIGH LATDbits.LATD2 = 1 ;
#define QTB_DRDY PORTDbits.RD2 ;
#define QTA_DRDY PORTDbits.RD5 ;
// FREQUENCY SELECT
#define _XTAL_FREQ 16000000
// PIN SETUP
void PIN_MANAGER_Initialize(void)
{
/**
LATx registers
*/
LATE = 0x00;
LATD = 0x00;
LATA = 0x00;
LATB = 0b00010000;
LATC = 0x00;
/**
TRISx registers
*/
TRISE = 0x00;
TRISA = 0x08;
TRISB = 0x01;
TRISC = 0b00010000;
TRISD = 0xEF;
PORTC = 0b00010010 ;
/**
ANSELx registers
*/
ANCON0 = 0x00;
ANCON1 = 0x00;
/**
WPUx registers
*/
WPUB = 0x00;
INTCON2bits.nRBPU = 1;
}
// SPI
void SPI_Initialize(void)
{
// SMP Middle; CKE Idle to Active;
SSPSTAT = 0b00000000;
// SSPEN enabled; WCOL no_collision; CKP Idle:High, Active:Low; SSPM FOSC/4; SSPOV no_overflow;
SSPCON1 = 0b00111010;
// SSPADD 0;
SSPADD = 0x00;
ADCON0 = 0 ;
ADCON1 = 0x0F ; //Makes all I/O digital
SCK_TRIS ;
SDO_TRIS ;
SDI_TRIS ;
QTA_SS_TRIS ;
QTB_SS_TRIS ;
QTA_DRDY_TRIS ;
QTB_DRDY_TRIS ;
}
signed char WriteSPI( unsigned char data_out )
{
unsigned char TempVar;
TempVar = SSPBUF; // Clears BF
PIR1bits.SSPIF = 0; // Clear interrupt flag
SSPCON1bits.WCOL = 0; //Clear any previous write collision
SSPBUF = data_out; // write byte to SSPBUF register
if ( SSPCON1 & 0x80 ) // test if write collision occurred
return ( -1 ); // if WCOL bit is set return negative #
else
while( !PIR1bits.SSPIF ); // wait until bus cycle complete
return ( 0 ); // if WCOL bit is not set return non-negative#
}
unsigned char ReadSPI( void )
{
unsigned char TempVar;
TempVar = SSPBUF; // Clear BF
PIR1bits.SSPIF = 0; // Clear interrupt flag
SSPBUF = 0x00; // initiate bus cycle
while(!PIR1bits.SSPIF); // wait until cycle complete
return ( SSPBUF ); // return with byte read
}
unsigned char DataRdySPI( void )
{
if ( SSPSTATbits.BF )
return ( +1 ); // data in SSPBUF register
else
return ( 0 ); // no data in SSPBUF register
}
// SOFTWARE EUART
void out_char(char character, char bit_order){
uint8_t i = 0;
RSOUT = 1 ; // MSB
__delay_ms(1);
RSOUT = 0 ; // START
__delay_us(100);
for (i = 8; i>0; --i){
if (bit_order){ // Bit order determines how you will put the bits, from left to right (MSB) or right to left (LSB)
RSOUT = (character & 0x80) ? 1:0; // in MSB you compare the left-most bit doing an AND with 0x80, and put 1 if true, 0 elsewhere.
character <<= 1; // Shift the character to the left, discrading the bit just sent
} else {
RSOUT = (character & 0x01); // in LSB you compare the right-most bit doing an AND with 0x01, and put 1 if true, 0 else.
character >>= 1; // Shift the character to the right, discrading the bit just sent
}
__delay_us(100);
}
RSOUT = 1 ; // STOP
}
void out_str(char * string, uint8_t len, char bit_order){
uint8_t i = 0;
for (i = 0; i< len; i++){
out_char(string[i], bit_order);
}
}
void SYSTEM_Initialize(void)
{
PIN_MANAGER_Initialize() ;
SPI_Initialize() ;
}
void main(void)
{
SYSTEM_Initialize() ;
while (1)
{
QTB_SS_LAT_LOW ; // Transmit data
char temp ;
WriteSPI(0x0F) ; // Send a byte
while(!DataRdySPI()) ; // wait for a data to arrive
temp = ReadSPI(); // Read a byte from the
QTB_SS_LAT_HIGH ; // Stop transmitting data
__delay_us(100) ;
}
}
c pic spi
This question is too broad, as you are essentially asking how to do the whole implementation. You either need to sync the signal with the SPI transmission, or sync the SPI with the signal. For example you can start a timer after the SPI flag does up and toggle the pin from there. This is why experienced devs read the timing specs of the part using SPI before picking it - because there exists so much dirty non-standard crap like this in the market and you really don't want to be stuck with a non-standard SPI implementation. Be extra careful before specifying Microchip/Atmel or ST parts.
– Lundin
Nov 20 '18 at 14:45
I cannot get my DRDY to be idle high. Is there something wrong in the code?
– M2T156
Nov 20 '18 at 15:04
add a comment |
I also have a problem with DRDY. I need to include DRDY. The pins for DRDY are RD2 and RD5. They are both inputs.
Here is the information for DRDY.
DRDY Pin
DRDY is an open-drain output (in SPI mode) or bidirectional pin (in UART mode) with an internal 20 k – 50 k pullup
resistor.
Most communications failures are the result of failure to properly observe the DRDY timing.
Serial communications pacing is controlled by this pin. Use of DRDY is critical to successful communications with the
QT1481. In either UART or SPI mode, the host is permitted to perform a data transfer only when DRDY has returned
high. Additionally, in UART mode, the QT1481 delays responses to the host if DRDY is being held low by the host.
After each byte transfer, DRDY goes low after a short delay and remains low until the QT1481 is ready for another
transfer. A short delay occurs before DRDY is driven low because the QT1481 may otherwise be busy and requires
a finite time to respond.
DRDY may go low for a microsecond only. During the period from the end of one transfer until DRDY goes low and
back high again, the host should not perform another transfer. Therefore, before each byte transmission the host
should first check that DRDY is high again.
If the host wants to perform a byte transfer with the QT1481 it should behave as follows:
1. Wait at least 100 µs after the previous transfer (time S5 in Figure 3-2 on page 23: DRDY is guaranteed to go
low before this 100 µs expires).
2. Wait until DRDY is high (it may already be high).
3. Perform the next transfer with the QT1481.
In most cases it takes up to 3 ms for DRDY to return high again. However, this time is longer with some commands
or if the STS_DEBUG setup is enabled, as follows:0x01 (Setups load): <20 ms0x02 (Low Level Cal and Offset): <20 ms
Add 15 ms to the above times if the STS_DEBUG setup is enabled.
Other DRDY specifications:
Min time DRDY is low: 1 µs
Max time DRDY is low after reset: 100 ms
The timing diagram is this: 
How can implement that?
The code I have written with my friend is written here:
#include <xc.h>
#include "PIC.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//#include <pic18f45k80.h>
#define MSB 1
#define LSB 0
// SPI PIN CONFIGURATION
#define SCK_TRIS TRISCbits.TRISC3 = 0 ;
#define SDO_TRIS TRISCbits.TRISC5 = 0 ;
#define SDI_TRIS TRISCbits.TRISC4 = 1 ;
#define QTA_SS_TRIS TRISDbits.TRISD4 = 0 ;
#define QTB_SS_TRIS TRISEbits.TRISE2 = 0 ;
#define QTA_SS_LAT_LOW LATDbits.LATD4 = 0 ;
#define QTA_SS_LAT_HIGH LATDbits.LATD4 = 1 ;
#define QTB_SS_LAT_LOW LATEbits.LATE2 = 0 ;
#define QTB_SS_LAT_HIGH LATEbits.LATE2 = 1 ;
#define QTA_DRDY_TRIS TRISDbits.TRISD5 = 1 ;
#define QTB_DRDY_TRIS TRISDbits.TRISD2 = 1 ;
#define QTA_DRDY_LAT_LOW LATDbits.LATD5 = 0 ;
#define QTA_DRDY_LAT_HIGH LATDbits.LAT52 = 1 ;
#define QTB_DRDY_LAT_LOW LATDbits.LAT25 = 0 ;
#define QTB_DRDY_LAT_HIGH LATDbits.LATD2 = 1 ;
#define QTB_DRDY PORTDbits.RD2 ;
#define QTA_DRDY PORTDbits.RD5 ;
// FREQUENCY SELECT
#define _XTAL_FREQ 16000000
// PIN SETUP
void PIN_MANAGER_Initialize(void)
{
/**
LATx registers
*/
LATE = 0x00;
LATD = 0x00;
LATA = 0x00;
LATB = 0b00010000;
LATC = 0x00;
/**
TRISx registers
*/
TRISE = 0x00;
TRISA = 0x08;
TRISB = 0x01;
TRISC = 0b00010000;
TRISD = 0xEF;
PORTC = 0b00010010 ;
/**
ANSELx registers
*/
ANCON0 = 0x00;
ANCON1 = 0x00;
/**
WPUx registers
*/
WPUB = 0x00;
INTCON2bits.nRBPU = 1;
}
// SPI
void SPI_Initialize(void)
{
// SMP Middle; CKE Idle to Active;
SSPSTAT = 0b00000000;
// SSPEN enabled; WCOL no_collision; CKP Idle:High, Active:Low; SSPM FOSC/4; SSPOV no_overflow;
SSPCON1 = 0b00111010;
// SSPADD 0;
SSPADD = 0x00;
ADCON0 = 0 ;
ADCON1 = 0x0F ; //Makes all I/O digital
SCK_TRIS ;
SDO_TRIS ;
SDI_TRIS ;
QTA_SS_TRIS ;
QTB_SS_TRIS ;
QTA_DRDY_TRIS ;
QTB_DRDY_TRIS ;
}
signed char WriteSPI( unsigned char data_out )
{
unsigned char TempVar;
TempVar = SSPBUF; // Clears BF
PIR1bits.SSPIF = 0; // Clear interrupt flag
SSPCON1bits.WCOL = 0; //Clear any previous write collision
SSPBUF = data_out; // write byte to SSPBUF register
if ( SSPCON1 & 0x80 ) // test if write collision occurred
return ( -1 ); // if WCOL bit is set return negative #
else
while( !PIR1bits.SSPIF ); // wait until bus cycle complete
return ( 0 ); // if WCOL bit is not set return non-negative#
}
unsigned char ReadSPI( void )
{
unsigned char TempVar;
TempVar = SSPBUF; // Clear BF
PIR1bits.SSPIF = 0; // Clear interrupt flag
SSPBUF = 0x00; // initiate bus cycle
while(!PIR1bits.SSPIF); // wait until cycle complete
return ( SSPBUF ); // return with byte read
}
unsigned char DataRdySPI( void )
{
if ( SSPSTATbits.BF )
return ( +1 ); // data in SSPBUF register
else
return ( 0 ); // no data in SSPBUF register
}
// SOFTWARE EUART
void out_char(char character, char bit_order){
uint8_t i = 0;
RSOUT = 1 ; // MSB
__delay_ms(1);
RSOUT = 0 ; // START
__delay_us(100);
for (i = 8; i>0; --i){
if (bit_order){ // Bit order determines how you will put the bits, from left to right (MSB) or right to left (LSB)
RSOUT = (character & 0x80) ? 1:0; // in MSB you compare the left-most bit doing an AND with 0x80, and put 1 if true, 0 elsewhere.
character <<= 1; // Shift the character to the left, discrading the bit just sent
} else {
RSOUT = (character & 0x01); // in LSB you compare the right-most bit doing an AND with 0x01, and put 1 if true, 0 else.
character >>= 1; // Shift the character to the right, discrading the bit just sent
}
__delay_us(100);
}
RSOUT = 1 ; // STOP
}
void out_str(char * string, uint8_t len, char bit_order){
uint8_t i = 0;
for (i = 0; i< len; i++){
out_char(string[i], bit_order);
}
}
void SYSTEM_Initialize(void)
{
PIN_MANAGER_Initialize() ;
SPI_Initialize() ;
}
void main(void)
{
SYSTEM_Initialize() ;
while (1)
{
QTB_SS_LAT_LOW ; // Transmit data
char temp ;
WriteSPI(0x0F) ; // Send a byte
while(!DataRdySPI()) ; // wait for a data to arrive
temp = ReadSPI(); // Read a byte from the
QTB_SS_LAT_HIGH ; // Stop transmitting data
__delay_us(100) ;
}
}
c pic spi
I also have a problem with DRDY. I need to include DRDY. The pins for DRDY are RD2 and RD5. They are both inputs.
Here is the information for DRDY.
DRDY Pin
DRDY is an open-drain output (in SPI mode) or bidirectional pin (in UART mode) with an internal 20 k – 50 k pullup
resistor.
Most communications failures are the result of failure to properly observe the DRDY timing.
Serial communications pacing is controlled by this pin. Use of DRDY is critical to successful communications with the
QT1481. In either UART or SPI mode, the host is permitted to perform a data transfer only when DRDY has returned
high. Additionally, in UART mode, the QT1481 delays responses to the host if DRDY is being held low by the host.
After each byte transfer, DRDY goes low after a short delay and remains low until the QT1481 is ready for another
transfer. A short delay occurs before DRDY is driven low because the QT1481 may otherwise be busy and requires
a finite time to respond.
DRDY may go low for a microsecond only. During the period from the end of one transfer until DRDY goes low and
back high again, the host should not perform another transfer. Therefore, before each byte transmission the host
should first check that DRDY is high again.
If the host wants to perform a byte transfer with the QT1481 it should behave as follows:
1. Wait at least 100 µs after the previous transfer (time S5 in Figure 3-2 on page 23: DRDY is guaranteed to go
low before this 100 µs expires).
2. Wait until DRDY is high (it may already be high).
3. Perform the next transfer with the QT1481.
In most cases it takes up to 3 ms for DRDY to return high again. However, this time is longer with some commands
or if the STS_DEBUG setup is enabled, as follows:0x01 (Setups load): <20 ms0x02 (Low Level Cal and Offset): <20 ms
Add 15 ms to the above times if the STS_DEBUG setup is enabled.
Other DRDY specifications:
Min time DRDY is low: 1 µs
Max time DRDY is low after reset: 100 ms
The timing diagram is this: 
How can implement that?
The code I have written with my friend is written here:
#include <xc.h>
#include "PIC.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//#include <pic18f45k80.h>
#define MSB 1
#define LSB 0
// SPI PIN CONFIGURATION
#define SCK_TRIS TRISCbits.TRISC3 = 0 ;
#define SDO_TRIS TRISCbits.TRISC5 = 0 ;
#define SDI_TRIS TRISCbits.TRISC4 = 1 ;
#define QTA_SS_TRIS TRISDbits.TRISD4 = 0 ;
#define QTB_SS_TRIS TRISEbits.TRISE2 = 0 ;
#define QTA_SS_LAT_LOW LATDbits.LATD4 = 0 ;
#define QTA_SS_LAT_HIGH LATDbits.LATD4 = 1 ;
#define QTB_SS_LAT_LOW LATEbits.LATE2 = 0 ;
#define QTB_SS_LAT_HIGH LATEbits.LATE2 = 1 ;
#define QTA_DRDY_TRIS TRISDbits.TRISD5 = 1 ;
#define QTB_DRDY_TRIS TRISDbits.TRISD2 = 1 ;
#define QTA_DRDY_LAT_LOW LATDbits.LATD5 = 0 ;
#define QTA_DRDY_LAT_HIGH LATDbits.LAT52 = 1 ;
#define QTB_DRDY_LAT_LOW LATDbits.LAT25 = 0 ;
#define QTB_DRDY_LAT_HIGH LATDbits.LATD2 = 1 ;
#define QTB_DRDY PORTDbits.RD2 ;
#define QTA_DRDY PORTDbits.RD5 ;
// FREQUENCY SELECT
#define _XTAL_FREQ 16000000
// PIN SETUP
void PIN_MANAGER_Initialize(void)
{
/**
LATx registers
*/
LATE = 0x00;
LATD = 0x00;
LATA = 0x00;
LATB = 0b00010000;
LATC = 0x00;
/**
TRISx registers
*/
TRISE = 0x00;
TRISA = 0x08;
TRISB = 0x01;
TRISC = 0b00010000;
TRISD = 0xEF;
PORTC = 0b00010010 ;
/**
ANSELx registers
*/
ANCON0 = 0x00;
ANCON1 = 0x00;
/**
WPUx registers
*/
WPUB = 0x00;
INTCON2bits.nRBPU = 1;
}
// SPI
void SPI_Initialize(void)
{
// SMP Middle; CKE Idle to Active;
SSPSTAT = 0b00000000;
// SSPEN enabled; WCOL no_collision; CKP Idle:High, Active:Low; SSPM FOSC/4; SSPOV no_overflow;
SSPCON1 = 0b00111010;
// SSPADD 0;
SSPADD = 0x00;
ADCON0 = 0 ;
ADCON1 = 0x0F ; //Makes all I/O digital
SCK_TRIS ;
SDO_TRIS ;
SDI_TRIS ;
QTA_SS_TRIS ;
QTB_SS_TRIS ;
QTA_DRDY_TRIS ;
QTB_DRDY_TRIS ;
}
signed char WriteSPI( unsigned char data_out )
{
unsigned char TempVar;
TempVar = SSPBUF; // Clears BF
PIR1bits.SSPIF = 0; // Clear interrupt flag
SSPCON1bits.WCOL = 0; //Clear any previous write collision
SSPBUF = data_out; // write byte to SSPBUF register
if ( SSPCON1 & 0x80 ) // test if write collision occurred
return ( -1 ); // if WCOL bit is set return negative #
else
while( !PIR1bits.SSPIF ); // wait until bus cycle complete
return ( 0 ); // if WCOL bit is not set return non-negative#
}
unsigned char ReadSPI( void )
{
unsigned char TempVar;
TempVar = SSPBUF; // Clear BF
PIR1bits.SSPIF = 0; // Clear interrupt flag
SSPBUF = 0x00; // initiate bus cycle
while(!PIR1bits.SSPIF); // wait until cycle complete
return ( SSPBUF ); // return with byte read
}
unsigned char DataRdySPI( void )
{
if ( SSPSTATbits.BF )
return ( +1 ); // data in SSPBUF register
else
return ( 0 ); // no data in SSPBUF register
}
// SOFTWARE EUART
void out_char(char character, char bit_order){
uint8_t i = 0;
RSOUT = 1 ; // MSB
__delay_ms(1);
RSOUT = 0 ; // START
__delay_us(100);
for (i = 8; i>0; --i){
if (bit_order){ // Bit order determines how you will put the bits, from left to right (MSB) or right to left (LSB)
RSOUT = (character & 0x80) ? 1:0; // in MSB you compare the left-most bit doing an AND with 0x80, and put 1 if true, 0 elsewhere.
character <<= 1; // Shift the character to the left, discrading the bit just sent
} else {
RSOUT = (character & 0x01); // in LSB you compare the right-most bit doing an AND with 0x01, and put 1 if true, 0 else.
character >>= 1; // Shift the character to the right, discrading the bit just sent
}
__delay_us(100);
}
RSOUT = 1 ; // STOP
}
void out_str(char * string, uint8_t len, char bit_order){
uint8_t i = 0;
for (i = 0; i< len; i++){
out_char(string[i], bit_order);
}
}
void SYSTEM_Initialize(void)
{
PIN_MANAGER_Initialize() ;
SPI_Initialize() ;
}
void main(void)
{
SYSTEM_Initialize() ;
while (1)
{
QTB_SS_LAT_LOW ; // Transmit data
char temp ;
WriteSPI(0x0F) ; // Send a byte
while(!DataRdySPI()) ; // wait for a data to arrive
temp = ReadSPI(); // Read a byte from the
QTB_SS_LAT_HIGH ; // Stop transmitting data
__delay_us(100) ;
}
}
c pic spi
c pic spi
edited Nov 20 '18 at 14:24
Mike
2,0031722
2,0031722
asked Nov 20 '18 at 14:10
M2T156M2T156
215
215
This question is too broad, as you are essentially asking how to do the whole implementation. You either need to sync the signal with the SPI transmission, or sync the SPI with the signal. For example you can start a timer after the SPI flag does up and toggle the pin from there. This is why experienced devs read the timing specs of the part using SPI before picking it - because there exists so much dirty non-standard crap like this in the market and you really don't want to be stuck with a non-standard SPI implementation. Be extra careful before specifying Microchip/Atmel or ST parts.
– Lundin
Nov 20 '18 at 14:45
I cannot get my DRDY to be idle high. Is there something wrong in the code?
– M2T156
Nov 20 '18 at 15:04
add a comment |
This question is too broad, as you are essentially asking how to do the whole implementation. You either need to sync the signal with the SPI transmission, or sync the SPI with the signal. For example you can start a timer after the SPI flag does up and toggle the pin from there. This is why experienced devs read the timing specs of the part using SPI before picking it - because there exists so much dirty non-standard crap like this in the market and you really don't want to be stuck with a non-standard SPI implementation. Be extra careful before specifying Microchip/Atmel or ST parts.
– Lundin
Nov 20 '18 at 14:45
I cannot get my DRDY to be idle high. Is there something wrong in the code?
– M2T156
Nov 20 '18 at 15:04
This question is too broad, as you are essentially asking how to do the whole implementation. You either need to sync the signal with the SPI transmission, or sync the SPI with the signal. For example you can start a timer after the SPI flag does up and toggle the pin from there. This is why experienced devs read the timing specs of the part using SPI before picking it - because there exists so much dirty non-standard crap like this in the market and you really don't want to be stuck with a non-standard SPI implementation. Be extra careful before specifying Microchip/Atmel or ST parts.
– Lundin
Nov 20 '18 at 14:45
This question is too broad, as you are essentially asking how to do the whole implementation. You either need to sync the signal with the SPI transmission, or sync the SPI with the signal. For example you can start a timer after the SPI flag does up and toggle the pin from there. This is why experienced devs read the timing specs of the part using SPI before picking it - because there exists so much dirty non-standard crap like this in the market and you really don't want to be stuck with a non-standard SPI implementation. Be extra careful before specifying Microchip/Atmel or ST parts.
– Lundin
Nov 20 '18 at 14:45
I cannot get my DRDY to be idle high. Is there something wrong in the code?
– M2T156
Nov 20 '18 at 15:04
I cannot get my DRDY to be idle high. Is there something wrong in the code?
– M2T156
Nov 20 '18 at 15:04
add a comment |
1 Answer
1
active
oldest
votes
No. Do not just write a bunch of code, then see what it does. That kind of shotgun (or, if you prefer, spaghetti-to-the-wall) approach is a waste of effort.
First, drop all those macros. Instead, write comments that describe the purpose of each chunk of code, like the first three assignments in your SPI_Initialize() function.
Next, convert your specification to pseudocode. The format does not matter much, just use something that lets you keep your mind focused on what the purpose is, rather than on the details on how to do it.
The datasheet says that with SPI, there are three outputs from the PIC (^SS, SCK, MOSI on the QT1481), and two inputs (^DRDY and MISO on the QT1481). I'll use those names for the data lines, and for their respective I/O pin names on the PIC.
The setup phase on the PIC should be simple:
Make ^DRDY an input
Make ^SS an output, set it HIGH
Make SCK an output, set it LOW
Make MOSI an output, set it LOW
Make MISO an input
Set up SPI using SCK, MOSI, MISO
Each transfer is a bidirectional one. Whenever you send data, you also receive data. The zero command is reserved for receiving multiple data, says the datasheet. So, you only need a function that sends a byte, and at the same time receives a byte:
Function SPITransfer(command):
Make sure at least 0.1ms has passed since the previous transfer.
Do:
Nothing
While (^DRDY is LOW)
Set ^SS LOW
response = Transfer(command)
Set ^SS HIGH
Return response
End Function
As I understand it, for PICs and properly initialized hardware SPI the response = Transfer(command) line is in C
SSPBUF = command;
while (!DataRdySPI())
;
response = SSPBUF;
You can also bit-bang it, in which case it is (in pseudocode):
response = 0
For bit = 7 down to 0, inclusive:
If (command & 128):
Set MOSI high
Else:
Set MOSI low
End If
Set SCK low
Sleep for a half period
command = command / 2
response = response * 2
If MISO high:
response = response + 1
End If
Set SCK high
Sleep for a half period
End For
but obviously the hardware SPI approach is better.
(When you get this working, you can use the hardware SPI without a wait loop from a timer interrupt, making the communications essentially transparent to the "main operation" of the PIC microcontroller. That requires a slightly different approach, with a command and response queues (of a few bytes), but will make it much easier for the PIC to do actual work, other than just scan the QT1481.)
After a reset, you essentially send 0x0F until you get 0xF0 back:
while (SPITransfer(0x0F) != 0xF0)
;
At this point, you have the steps you need to implement in C. OP also has the hardware (an oscilloscope) to verify their code works.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53394889%2fdrdy-pic18f45k80-to-qt1481%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
No. Do not just write a bunch of code, then see what it does. That kind of shotgun (or, if you prefer, spaghetti-to-the-wall) approach is a waste of effort.
First, drop all those macros. Instead, write comments that describe the purpose of each chunk of code, like the first three assignments in your SPI_Initialize() function.
Next, convert your specification to pseudocode. The format does not matter much, just use something that lets you keep your mind focused on what the purpose is, rather than on the details on how to do it.
The datasheet says that with SPI, there are three outputs from the PIC (^SS, SCK, MOSI on the QT1481), and two inputs (^DRDY and MISO on the QT1481). I'll use those names for the data lines, and for their respective I/O pin names on the PIC.
The setup phase on the PIC should be simple:
Make ^DRDY an input
Make ^SS an output, set it HIGH
Make SCK an output, set it LOW
Make MOSI an output, set it LOW
Make MISO an input
Set up SPI using SCK, MOSI, MISO
Each transfer is a bidirectional one. Whenever you send data, you also receive data. The zero command is reserved for receiving multiple data, says the datasheet. So, you only need a function that sends a byte, and at the same time receives a byte:
Function SPITransfer(command):
Make sure at least 0.1ms has passed since the previous transfer.
Do:
Nothing
While (^DRDY is LOW)
Set ^SS LOW
response = Transfer(command)
Set ^SS HIGH
Return response
End Function
As I understand it, for PICs and properly initialized hardware SPI the response = Transfer(command) line is in C
SSPBUF = command;
while (!DataRdySPI())
;
response = SSPBUF;
You can also bit-bang it, in which case it is (in pseudocode):
response = 0
For bit = 7 down to 0, inclusive:
If (command & 128):
Set MOSI high
Else:
Set MOSI low
End If
Set SCK low
Sleep for a half period
command = command / 2
response = response * 2
If MISO high:
response = response + 1
End If
Set SCK high
Sleep for a half period
End For
but obviously the hardware SPI approach is better.
(When you get this working, you can use the hardware SPI without a wait loop from a timer interrupt, making the communications essentially transparent to the "main operation" of the PIC microcontroller. That requires a slightly different approach, with a command and response queues (of a few bytes), but will make it much easier for the PIC to do actual work, other than just scan the QT1481.)
After a reset, you essentially send 0x0F until you get 0xF0 back:
while (SPITransfer(0x0F) != 0xF0)
;
At this point, you have the steps you need to implement in C. OP also has the hardware (an oscilloscope) to verify their code works.
add a comment |
No. Do not just write a bunch of code, then see what it does. That kind of shotgun (or, if you prefer, spaghetti-to-the-wall) approach is a waste of effort.
First, drop all those macros. Instead, write comments that describe the purpose of each chunk of code, like the first three assignments in your SPI_Initialize() function.
Next, convert your specification to pseudocode. The format does not matter much, just use something that lets you keep your mind focused on what the purpose is, rather than on the details on how to do it.
The datasheet says that with SPI, there are three outputs from the PIC (^SS, SCK, MOSI on the QT1481), and two inputs (^DRDY and MISO on the QT1481). I'll use those names for the data lines, and for their respective I/O pin names on the PIC.
The setup phase on the PIC should be simple:
Make ^DRDY an input
Make ^SS an output, set it HIGH
Make SCK an output, set it LOW
Make MOSI an output, set it LOW
Make MISO an input
Set up SPI using SCK, MOSI, MISO
Each transfer is a bidirectional one. Whenever you send data, you also receive data. The zero command is reserved for receiving multiple data, says the datasheet. So, you only need a function that sends a byte, and at the same time receives a byte:
Function SPITransfer(command):
Make sure at least 0.1ms has passed since the previous transfer.
Do:
Nothing
While (^DRDY is LOW)
Set ^SS LOW
response = Transfer(command)
Set ^SS HIGH
Return response
End Function
As I understand it, for PICs and properly initialized hardware SPI the response = Transfer(command) line is in C
SSPBUF = command;
while (!DataRdySPI())
;
response = SSPBUF;
You can also bit-bang it, in which case it is (in pseudocode):
response = 0
For bit = 7 down to 0, inclusive:
If (command & 128):
Set MOSI high
Else:
Set MOSI low
End If
Set SCK low
Sleep for a half period
command = command / 2
response = response * 2
If MISO high:
response = response + 1
End If
Set SCK high
Sleep for a half period
End For
but obviously the hardware SPI approach is better.
(When you get this working, you can use the hardware SPI without a wait loop from a timer interrupt, making the communications essentially transparent to the "main operation" of the PIC microcontroller. That requires a slightly different approach, with a command and response queues (of a few bytes), but will make it much easier for the PIC to do actual work, other than just scan the QT1481.)
After a reset, you essentially send 0x0F until you get 0xF0 back:
while (SPITransfer(0x0F) != 0xF0)
;
At this point, you have the steps you need to implement in C. OP also has the hardware (an oscilloscope) to verify their code works.
add a comment |
No. Do not just write a bunch of code, then see what it does. That kind of shotgun (or, if you prefer, spaghetti-to-the-wall) approach is a waste of effort.
First, drop all those macros. Instead, write comments that describe the purpose of each chunk of code, like the first three assignments in your SPI_Initialize() function.
Next, convert your specification to pseudocode. The format does not matter much, just use something that lets you keep your mind focused on what the purpose is, rather than on the details on how to do it.
The datasheet says that with SPI, there are three outputs from the PIC (^SS, SCK, MOSI on the QT1481), and two inputs (^DRDY and MISO on the QT1481). I'll use those names for the data lines, and for their respective I/O pin names on the PIC.
The setup phase on the PIC should be simple:
Make ^DRDY an input
Make ^SS an output, set it HIGH
Make SCK an output, set it LOW
Make MOSI an output, set it LOW
Make MISO an input
Set up SPI using SCK, MOSI, MISO
Each transfer is a bidirectional one. Whenever you send data, you also receive data. The zero command is reserved for receiving multiple data, says the datasheet. So, you only need a function that sends a byte, and at the same time receives a byte:
Function SPITransfer(command):
Make sure at least 0.1ms has passed since the previous transfer.
Do:
Nothing
While (^DRDY is LOW)
Set ^SS LOW
response = Transfer(command)
Set ^SS HIGH
Return response
End Function
As I understand it, for PICs and properly initialized hardware SPI the response = Transfer(command) line is in C
SSPBUF = command;
while (!DataRdySPI())
;
response = SSPBUF;
You can also bit-bang it, in which case it is (in pseudocode):
response = 0
For bit = 7 down to 0, inclusive:
If (command & 128):
Set MOSI high
Else:
Set MOSI low
End If
Set SCK low
Sleep for a half period
command = command / 2
response = response * 2
If MISO high:
response = response + 1
End If
Set SCK high
Sleep for a half period
End For
but obviously the hardware SPI approach is better.
(When you get this working, you can use the hardware SPI without a wait loop from a timer interrupt, making the communications essentially transparent to the "main operation" of the PIC microcontroller. That requires a slightly different approach, with a command and response queues (of a few bytes), but will make it much easier for the PIC to do actual work, other than just scan the QT1481.)
After a reset, you essentially send 0x0F until you get 0xF0 back:
while (SPITransfer(0x0F) != 0xF0)
;
At this point, you have the steps you need to implement in C. OP also has the hardware (an oscilloscope) to verify their code works.
No. Do not just write a bunch of code, then see what it does. That kind of shotgun (or, if you prefer, spaghetti-to-the-wall) approach is a waste of effort.
First, drop all those macros. Instead, write comments that describe the purpose of each chunk of code, like the first three assignments in your SPI_Initialize() function.
Next, convert your specification to pseudocode. The format does not matter much, just use something that lets you keep your mind focused on what the purpose is, rather than on the details on how to do it.
The datasheet says that with SPI, there are three outputs from the PIC (^SS, SCK, MOSI on the QT1481), and two inputs (^DRDY and MISO on the QT1481). I'll use those names for the data lines, and for their respective I/O pin names on the PIC.
The setup phase on the PIC should be simple:
Make ^DRDY an input
Make ^SS an output, set it HIGH
Make SCK an output, set it LOW
Make MOSI an output, set it LOW
Make MISO an input
Set up SPI using SCK, MOSI, MISO
Each transfer is a bidirectional one. Whenever you send data, you also receive data. The zero command is reserved for receiving multiple data, says the datasheet. So, you only need a function that sends a byte, and at the same time receives a byte:
Function SPITransfer(command):
Make sure at least 0.1ms has passed since the previous transfer.
Do:
Nothing
While (^DRDY is LOW)
Set ^SS LOW
response = Transfer(command)
Set ^SS HIGH
Return response
End Function
As I understand it, for PICs and properly initialized hardware SPI the response = Transfer(command) line is in C
SSPBUF = command;
while (!DataRdySPI())
;
response = SSPBUF;
You can also bit-bang it, in which case it is (in pseudocode):
response = 0
For bit = 7 down to 0, inclusive:
If (command & 128):
Set MOSI high
Else:
Set MOSI low
End If
Set SCK low
Sleep for a half period
command = command / 2
response = response * 2
If MISO high:
response = response + 1
End If
Set SCK high
Sleep for a half period
End For
but obviously the hardware SPI approach is better.
(When you get this working, you can use the hardware SPI without a wait loop from a timer interrupt, making the communications essentially transparent to the "main operation" of the PIC microcontroller. That requires a slightly different approach, with a command and response queues (of a few bytes), but will make it much easier for the PIC to do actual work, other than just scan the QT1481.)
After a reset, you essentially send 0x0F until you get 0xF0 back:
while (SPITransfer(0x0F) != 0xF0)
;
At this point, you have the steps you need to implement in C. OP also has the hardware (an oscilloscope) to verify their code works.
answered Nov 20 '18 at 16:07
Nominal AnimalNominal Animal
30.3k33462
30.3k33462
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53394889%2fdrdy-pic18f45k80-to-qt1481%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This question is too broad, as you are essentially asking how to do the whole implementation. You either need to sync the signal with the SPI transmission, or sync the SPI with the signal. For example you can start a timer after the SPI flag does up and toggle the pin from there. This is why experienced devs read the timing specs of the part using SPI before picking it - because there exists so much dirty non-standard crap like this in the market and you really don't want to be stuck with a non-standard SPI implementation. Be extra careful before specifying Microchip/Atmel or ST parts.
– Lundin
Nov 20 '18 at 14:45
I cannot get my DRDY to be idle high. Is there something wrong in the code?
– M2T156
Nov 20 '18 at 15:04