[5] Ejemplos del protocolo de comunicación hardware análisis SPI no estándar (SPI de tres hilos)

1. Introducción

        Dado el blog anterior una explicación detallada de la historia SPI nivel de desarrollo, diagramas de tiempo, código de referencia. En la práctica, sin embargo, la norma SPI muchos han sido empaquetado en una biblioteca, tales como el pastel de frambuesa, el paquete inferior FPGA, una variedad de bibliotecas de terceros. El uso real de la temporización usamos c código para simular el spi, por lo general solo chip, no hay soporte biblioteca de terceros, sólo se puede utilizar para GPIO simular y spi simulado, de acuerdo con la tasa de la frecuencia de un solo chip, puerto GPIO la velocidad de conmutación ( más de unos pocos diferencia llamadas a funciones de tiempo es grande) relacionados. Por lo que yo sé, probablemente alrededor de 200K a 800K. Nuestra SPI es conocido como un protocolo para soportar la transmisión de datos a alta velocidad y recepción, esta frecuencia de reloj se siente un poco mal por su nombre científico.

        En realidad, cada proyecto es diferente, todos los proyectos no son sólo para la búsqueda de rápido, pero debe ser la búsqueda de la estabilidad. Seleccione la velocidad más estable, haciendo coincidir sus propios proyectos, se trata de un proyecto exitoso.

        Simulación spi problema más grave es GPIO excepción boca. Piense en ello, si SDI, SDO GPIO hay un punto en el error de volteo tiempo, hará que toda la operación para producir datos de corrección que no es, sin duda, los datos esperados, y la colocación de este tipo de problemas a menudo requiere el uso de una apropiación de la forma de onda del osciloscopio a saber. Por lo tanto, a menos que un último recurso, recomendaciones o elegir MCU spi con un estándar, o la necesidad de apoyar las bibliotecas de terceros, con el fin de hacer la operación más segura.

Ejemplo 2. (CMT2300A)

        Cada chip tiene sus requisitos de tiempo apropiados, así como la tasa de reloj máxima compatible. La velocidad del reloj de chip de hasta 5 m, y su secuencia que comprende el registro de lectura, la escritura en el registro, y la escritura FIFO FIFO leen cuatro instrucciones.

2.1 Especificaciones de temporización

        requisitos de tiempo desde el punto de vista, sabemos que diferentes estándar de tres y de cuatro hilos lugar SPI SPI (en este chip solamente, no quiere decir que otro spi), SPI es tres líneas comparten un puerto de datos (tanto SDIO), la escritura de datos y en que IO leer, y es controlada por dos señales de control representativas del registro operativo o fifo turno.

        Además, antes también se observa la operación de que, durante la operación de conmutación, y al final, cómo las necesidades de la línea de control a controlar, y el tiempo requerido, la necesidad de ajustar la forma de onda usando el osciloscopio para rastreo.

2,2 triplete código de ejemplo spi (consulte el código oficial documento)

#define SPI_CLK_PIN       (1)
#define SPI_CS_PIN        (2)
#define SPI_MISO_PIN      (3) //SDI与SDO共用一个gpio 当然也可以只定义一个
#define SPI_MOSI_PIN      (3)
#define SPI_FCS_PIN       (4)

void GPIO_Init(int pin , int mode)
{
    if(mode == 0)//输入上拉
    {
        iot_gpio_close(pin);
        iot_gpio_open_as_input(pin);//GPIO_Functional_Config_Bit(port , pin , FUNCTION_INPUT );//输入
        iot_gpio_set_pull_mode(pin, GPIO_PULL_NONE);//GPIO_Pull_Up_Config_Bit(port , pin , ENABLE );//上拉			
    }
    else
    {
        iot_gpio_close(pin);
        iot_gpio_open_as_output(pin);//GPIO_Functional_Config_Bit(port , pin , FUNCTION_OUTPUT );//输出
        iot_gpio_set_opendrain_mode(pin, GPIO_DRAIN_NORMAL);
    }				
}

/* ************************************************************************
*  The following need to be modified by user
*  ************************************************************************ */
#define SET_GPIO_OUT(x)             GPIO_Init(x, GPIO_OUTPUT)
#define SET_GPIO_IN(x)              GPIO_Init(x, GPIO_INPUT)

#define SET_GPIO_H(x)               iot_gpio_value_set(x,1)
#define SET_GPIO_L(x)               iot_gpio_value_set(x,0)
#define READ_GPIO_PIN(x)			iot_gpio_value_get(x)
//////////////

#define cmt_spi3_csb_out()      SET_GPIO_OUT(SPI_CS_PIN)
#define cmt_spi3_fcsb_out()     SET_GPIO_OUT(SPI_FCS_PIN)
#define cmt_spi3_sclk_out()     SET_GPIO_OUT(SPI_CLK_PIN)
#define cmt_spi3_sdio_out()		SET_GPIO_OUT(SPI_MOSI_PIN)
#define cmt_spi3_sdio_in()		SET_GPIO_IN(SPI_MOSI_PIN)

#define cmt_spi3_csb_1()        SET_GPIO_H(SPI_CS_PIN)
#define cmt_spi3_csb_0()        SET_GPIO_L(SPI_CS_PIN)

#define cmt_spi3_fcsb_1()       SET_GPIO_H(SPI_FCS_PIN)
#define cmt_spi3_fcsb_0()       SET_GPIO_L(SPI_FCS_PIN)
    
#define cmt_spi3_sclk_1()       SET_GPIO_H(SPI_CLK_PIN)
#define cmt_spi3_sclk_0()       SET_GPIO_L(SPI_CLK_PIN)

#define cmt_spi3_sdio_1()       SET_GPIO_H(SPI_MOSI_PIN)
#define cmt_spi3_sdio_0()       SET_GPIO_L(SPI_MOSI_PIN)
#define cmt_spi3_sdio_read()    READ_GPIO_PIN(SPI_MOSI_PIN)
/* ************************************************************************ */

void cmt_spi3_delay(void)
{
    u16 n = 2;
    while(n--);
}

void cmt_spi3_delay_us(void)
{
    u16 n = 1;
    while(n--);
}

uint32_t RF_Spi_Init(void)
{
	cmt_spi3_csb_out();
    cmt_spi3_csb_1();
    cmt_spi3_csb_out();
    cmt_spi3_csb_1();   
    
	cmt_spi3_sclk_out();
    cmt_spi3_sclk_0();
    cmt_spi3_sclk_out();
    cmt_spi3_sclk_0();  
    
	cmt_spi3_sdio_out();
    cmt_spi3_sdio_1();
    cmt_spi3_sdio_out();
    cmt_spi3_sdio_1();
    
	cmt_spi3_fcsb_out();
    cmt_spi3_fcsb_1();
    cmt_spi3_fcsb_out();
    cmt_spi3_fcsb_1(); 

    cmt_spi3_delay();
}

void cmt_spi3_send(u8 data8)
{
    u8 i;

    for(i=0; i<8; i++)
    {
        cmt_spi3_sclk_0();
        /* Send byte on the rising edge of SCLK */
        if(data8 & 0x80)
            cmt_spi3_sdio_1();
        else            
            cmt_spi3_sdio_0();
        //cmt_spi3_delay();
        data8 <<= 1;
        cmt_spi3_sclk_1();
        cmt_spi3_delay();
    }
}

u8 cmt_spi3_recv(void)
{
    u8 i;
	
    u8 data8 = 0xFF;
    for(i=0; i<8; i++)
    {
        cmt_spi3_sclk_0();
        cmt_spi3_delay();
        data8 <<= 1;
        cmt_spi3_sclk_1();
        /* Read byte on the rising edge of SCLK */
        if(cmt_spi3_sdio_read())
		//if (PADIN & 0x20)
            data8 |= 0x01;
        else
            data8 &= ~0x01;
    }
    return data8;
}

void cmt_spi3_write(u8 addr, u8 dat)
{
    cmt_spi3_sdio_1();
    cmt_spi3_csb_0();

    /* > 0.5 SCLK cycle */
    /* r/w = 0 */
    cmt_spi3_send(addr&0x7F);
    cmt_spi3_send(dat);
    cmt_spi3_sclk_0();
    /* > 0.5 SCLK cycle */
    cmt_spi3_csb_1();
    cmt_spi3_sdio_1();
}

void cmt_spi3_read(u8 addr, u8* p_dat)
{
    cmt_spi3_sdio_1();
    cmt_spi3_csb_0();
    /* > 0.5 SCLK cycle */
    /* r/w = 1 */
    cmt_spi3_send(addr|0x80);
    /* Must set SDIO to input before the falling edge of SCLK */
    cmt_spi3_sdio_in();
    *p_dat = cmt_spi3_recv();
    cmt_spi3_sclk_0();
    /* > 0.5 SCLK cycle */
    cmt_spi3_csb_1();
    cmt_spi3_sdio_1();
    
	cmt_spi3_sdio_out();
}

void cmt_spi3_write_fifo(u8* p_buf, u16 len)
{
    u16 i;

    for(i=0; i<len; )
    {
        cmt_spi3_fcsb_0();
        /* > 1 SCLK cycle */
        cmt_spi3_send(p_buf[i]);
        cmt_spi3_sclk_0();
        /* > 2 us */
        cmt_spi3_fcsb_1();
        /* > 4 us */
        i++;
    }
}

u8 cmt_spi3_read_fifo(u8* p_buf, u8 len)
{
    u8 i=0;
	
    cmt_spi3_sdio_in();
	for(i=0; i<len; i++)
	{
		cmt_spi3_fcsb_0();
		/* > 1 SCLK cycle */
		p_buf[i] = cmt_spi3_recv();
		cmt_spi3_sclk_0();
		/* > 2 us */
		cmt_spi3_delay_us();
		cmt_spi3_fcsb_1();
		/* > 4 us */
		cmt_spi3_delay_us();
	}
	cmt_spi3_sdio_out();
	return i;
}

3. Resumen

        Cuando se utiliza un nuevo chip, en primer lugar hay que aclarar sus requerimientos de tiempo. Al igual que esta patatas fritas caseras, que se explica en gran detalle en el documento de inicio rápido, puede desarrollar rápidamente. ¿Cómo sé si el chip con la comunicación SPI, el más intuitivo es usar un osciloscopio formas de onda para agarrar cuatro líneas, cada análisis, y luego encontrar un registro, el intento puede leer, escribir, leer, leer para determinar foto de éxito y, además, algunos chips habrá algún modo de prueba, tales como la función de apoyo a la lectura FIFO-back, para que pueda hacer los análisis correspondientes.

        Finalmente, si el soporte subyacente FPGA tres líneas en la línea 4, a continuación, se puede utilizar el correspondiente más paquete de funciones de interfaz, la parte inferior de un paquete de funciones como sigue:

typedef struct spi_xfer_buf
{
    struct spi_xfer_buf *p_nt;
    /** bytes for recieving or for transmiting. */
    int size;
    /** bytes recieved or transmited  */
    int xfer_size;
    char *rxbuf;
    char *txbuf;
}xfer_buf;
uint32_t iot_spi_write_one_data(char *data, int len)
{
    xfer_buf spi_tx;

    if ((NULL == data) || (0 >= len))
    {
        return ERR_FAIL;
    }

    spi_tx.p_nt = NULL;
    spi_tx.txbuf = data;
    spi_tx.rxbuf = NULL;
    spi_tx.size = len;

    if(-1 == iot_spi_poll_transfer(DEV_RF_SPI, &spi_tx))
    {
        return ERR_FAIL;
    }

    return ERR_OK;
}

uint32_t iot_spi_read_one_data(xfer_buf *xbuf)
{
    if ((NULL == xbuf))
    {
        return 1;
    }

    if(-1 == iot_spi_poll_transfer(DEV_RF_SPI, xbuf))
    {
        return 1;
    }

    return 0;
}

//api
void spi3_read(uint8_t addr, uint8_t* p_dat)
{
	char p_addr[1];

    p_addr[0] = (char)(addr | 0x80);

    xfer_buf xbuf[2];
    xbuf[0].p_nt = &xbuf[1];
    xbuf[0].txbuf = p_addr;
    xbuf[0].rxbuf = NULL;
    xbuf[0].size = 1;

    xbuf[1].p_nt = NULL;
    xbuf[1].txbuf = NULL;
    xbuf[1].rxbuf = p_dat;
    xbuf[1].size = 1;

    SCS_ENABLE;
    iot_spi_read_one_data(xbuf);
    SCS_DISABLE;
}

 

Publicado 41 artículos originales · ganado elogios 54 · Vistas a 40000 +

Supongo que te gusta

Origin blog.csdn.net/sishuihuahua/article/details/105047926
Recomendado
Clasificación