CH376 chip software simulates the hardware abstraction layer SPI_SW of SPI serial connection

/* CH376 chip software simulates hardware abstraction layer V1.0 of SPI serial connection */
/* Provides I/O interface subroutines */


#include "HAL.H"


/* The hardware connection method in this example is as follows (practical application The circuit can refer to the following definitions and subroutines) */
/* MCU pin CH376 chip pin
      P1.4                  SCS
      P1.5                  SDI
      P1.6                  SDO
      P1.7                  SCK       */
sbit P14 = P1^4;
sbit P15 = P1^5;
sbit P16 = P1^6;
sbit P17 = P1^7;
#define CH376_SPI_SCS P14 /* Assume the SCS pin of CH376*/
#define CH376_SPI_SDI P15 /* Assume the SDI pin of CH376*/ #define CH376_SPI_SDO P16 /* Assume the SDO pin of CH376*/ #define CH376_SPI_SCK P17 /* Assume the SCK pin of CH376 */ /*#define CH376_SPI_BZ P10*/ /* Assume the BZ pin of CH376*/ #define CH376_INT_WIRE INT0 /* Assume the INT# pin of CH376, if it is not connected, you can also query the SDO pin that doubles as interrupt output Status implementation*/ void CH376_PORT_INIT ( void ) /* Since software is used to simulate SPI read and write timing, initialization is performed*/ { /* If it is a hardware SPI interface, then mode3(CPOL=1&CPHA=1) or mode0(CPOL= 0&CPHA=0), CH376 samples input at the rising edge of the clock, output at the falling edge, the data bit is high first*/ CH376_SPI_SCS = 1; /* Disable SPI chip selection*/












CH376_SPI_SCK = 1; /* The default is high level, SPI mode 3, SPI mode 0 can also be used, but the simulation program may need to be slightly modified*/
/* For bidirectional I/O pins to simulate SPI interface, it must be here Set SPI_SCS, SPI_SCK, SPI_SDI as the output direction, SPI_SDO as the input direction*/
}


void mDelay0_5uS ( void ) /* at least 0.5uS delay, adjusted according to the main frequency of the microcontroller*/ { } void Spi376OutByte ( UINT8 d ) /* SPI output 8 One-digit data*/ { /* If it is a hardware SPI interface, it should first write the data to the SPI data register, and then query the SPI status register to wait for the SPI byte transfer to complete*/ UINT8 i; for ( i = 0; i < 8; i ++ ) { CH376_SPI_SCK = 0; if ( d & 0x80 ) CH376_SPI_SDI = 1; else CH376_SPI_SDI = 0; d <<= 1; /* data bits are MSB first */ CH376_SPI_SCK = 1; /* CH376 is in Clock rising edge sample input*/ } } UINT8 Spi376InByte

















( void ) /* SPI input 8-bit data*/
{ /* If it is a hardware SPI interface, it should first query the SPI status register to wait for the SPI byte transfer to complete, and then read the data from the SPI data register */
UINT8 i, d;
d = 0;
for ( i = 0; i < 8; i ++ ) {
CH376_SPI_SCK = 0; /* CH376 outputs at the falling edge of the clock*/
d <<= 1; /* Data bits are high order first* /
if ( CH376_SPI_SDO ) d ++;
CH376_SPI_SCK = 1;
}
return( d );
}


#define xEndCH376Cmd( ) { CH376_SPI_SCS = 1; } /* SPI chip selection is invalid, end CH376 command, only for SPI interface mode*/


void xWriteCH376Cmd ( UINT8 mCmd ) /* Write command to CH376*/ { #ifdef CH376_SPI_BZ UINT8 i; #endif CH376_SPI_SCS = 1; /* Prevent SPI chip selection from not being disabled by xEndCH376Cmd before*/





mDelay0_5uS( );
/* For bidirectional I/O pin analog SPI interface, you must ensure that SPI_SCS, SPI_SCK, SPI_SDI are set as output direction, and SPI_SDO is input direction*/
CH376_SPI_SCS = 0; /* SPI chip selection is valid*/
Spi376OutByte ( mCmd ); /* Issue command code*/
#ifdef CH376_SPI_BZ
for ( i = 30; i != 0 && CH376_SPI_BZ; -- i ); /* SPI busy status query, wait for CH376 to be not busy, or the delay of the following line 1.5uS instead of */
#else
mDelay0_5uS( ); mDelay0_5uS( ); mDelay0_5uS( ); /* Delay 1.5uS to ensure that the read and write cycle is greater than 1.5uS, or replace the status query with the above line */
#endif
}


#ifdef FOR_LOW_SPEED_MCU / * No delay required*/
#define xWriteCH376Data( d ) { Spi376OutByte( d ); } /* Write data to CH376*/
#define xReadCH376Data( ) ( Spi376InByte( ) ) /* Read data from CH376*/
#else
void xWriteCH376Data( UINT8 mData ) /* Write data to CH376*/
{
Spi376OutByte( mData );
// mDelay0_5uS( ); /* Ensure that the read/write cycle is greater than 0.6uS */
}
UINT8 xReadCH376Data( void ) /* Read data from CH376*/
{
// mDelay0_5uS( ); /* Make sure the read/write cycle is greater than 0.6uS */
return( Spi376InByte( ) );
}
#endif


/* Query CH376 interrupt (INT# low level) */
UINT8 Query376Interrupt( void )
{
#ifdef CH376_INT_WIRE
return( CH376_INT_WIRE ? FALSE : TRUE ); /* If the interrupt pin of CH376 is connected, directly query the interrupt pin*/
#else
return( CH376_SPI_SDO ? FALSE : TRUE ); /* If the interrupt pin of CH376 is not connected, then Query the state of the SDO pin that doubles as an interrupt output */
#endif
}


UINT8 mInitCH376Host ( void ) /* Initialize CH376 */
{
UINT8 res; CH376_PORT_INIT( );  /* Interface hardware initialization*/ xWriteCH376Cmd( CMD11_CHECK_EXIST );   /* Test the communication interface between MCU and CH376 */ xWriteCH376Data( 0x65 ) ; res = xReadCH376Data ( ); xEndCH376Cmd ( ); if ( res != 0x9A ) return( ERR_USB_UNKNOWN ); /* The communication interface is not normal, the possible reasons are: abnormal interface connection, influence of other devices (chip selection is not unique), serial port baud rate, Always reset, the crystal oscillator does not work*/ xWriteCH376Cmd( CMD11_SET_USB_MODE ); /* Device USB working mode*/ xWriteCH376Data( 0x06 ); mDelayuS( 20 ); res = xReadCH376Data( ); xEndCH376Cmd( ); #ifndef CH376_INT_WIRE #ifdef












CH376_SPI_SDO
xWriteCH376Cmd( CMD20_SET_SDO_INT ); /* Set the interrupt mode of SDO pin of SPI*/
xWriteCH376Data( 0x16 );
xWriteCH376Data( 0x90 ); /* SDO pin also serves as interrupt request output when SCS chip selection is invalid*/ xEndCH376Cmd( ) ; #endif #endif if ( res == CMD_RET_SUCCESS ) return( USB_INT_SUCCESS ); else return( ERR_USB_UNKNOWN ); /* set mode error */ }





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324811026&siteId=291194637
SPI