Autor Tema: SPI Harmony  (Leído 2426 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2976
SPI Harmony
« en: 08 de Mayo de 2018, 15:27:36 »
Buenas, a ver si alguien me echa una mano con esto, hace tiempo que no uso los PIC y estoy un poco perdido con las librerías estas nuevas.

Estoy usando un PIC32MZ1024EFG100, quiero utilizar el SPI 4 para manejar un MCP41HV51, pero no me termina de funcionar, en principio solo quiero darle ordenes, no me haría falta leerlo, ademas que la lectura es un poco rara ya que el MCP41HV51 empieza a responder antes de acabar de mandar un comando, así que de momento solo escribir.

He probado varios ejemplos de la documentación y de los proyectos pero ninguno termina de funcionar bien, este es uno de ellos por ejemplo:

Código: [Seleccionar]
#include "app.h"



//typedef unsigned char SPI_DATA_TYPE;
APP_DATA appData;


/* SPI2 Driver RX buffer  */
SPI_DATA_TYPE __attribute__ ((coherent)) drvSPI2RXbuffer[MAX_NUM_OF_BYTES_IN_BUF];

/* SPI1 Driver TX buffer  */
SPI_DATA_TYPE __attribute__ ((coherent)) drvSPI1TXbuffer[MAX_NUM_OF_BYTES_IN_BUF];

context gBufferContext;

void APP_Initialize ( void )
{
    appData.state = APP_STATE_INIT;
    appData.masterState = APP_STATE_SPI1_MASTER_WR;
    appData.slaveState = APP_STATE_SPI2_SLAVE_RD;

    appData.drvSPI1Handle= DRV_HANDLE_INVALID;
    appData.drvSPI2Handle= DRV_HANDLE_INVALID;
   
    WLAT_POTOff();
   
    SPI_CS2_POTOff();
   
   
    drvSPI1TXbuffer[0]=0x04;
}


void APP_Tasks ( void )
{
    switch ( appData.state )
    {
        case APP_STATE_INIT:
        {
            if(appData.drvSPI1Handle == DRV_HANDLE_INVALID)
            {
                appData.drvSPI1Handle = DRV_SPI_Open( DRV_SPI_INDEX_0,DRV_IO_INTENT_READWRITE );
                appData.state = APP_STATE_CHECK_DRVR_STATE;
            }   
            break;
        }

        case APP_STATE_CHECK_DRVR_STATE:
        {
            /* Check the SPI1 driver handler */
            if (appData.drvSPI1Handle == DRV_HANDLE_INVALID )
            {
                /* Set the app state to initialization */
                appData.state   = APP_STATE_INIT;
                return;
            }
            /* Driver instances are now "open". Start transmitting data between Master and Slave*/
            appData.state = APP_STATE_TRANSFER_DATA_BTWN_MASTER_SLAVE;
            break;
        }
       
        /* Start the Application data transfer between SP1 (Master) and SPI2 (Slave)*/
        case APP_STATE_TRANSFER_DATA_BTWN_MASTER_SLAVE:
        {
               
            /*SPI Driver Client 2.  Run the Master Task*/
            APP_SPI_MASTER_Task();
           break;
        }
       
       
        case APP_STATE_SERVICE_TASKS:
        {
       
            break;
        }
       
        default:
        {
            break;
        }
    }
}


void APP_SPI_MASTER_Task(void)
{
    switch(appData.masterState)
    {
         /*SPI1 TX*/
        case APP_STATE_SPI1_MASTER_WR:
        {
            /* Populate the buffer context with Tx Buffer ptr for the Buffer Event Handler */
            gBufferContext.SPI1TxBufferRef = &drvSPI1TXbuffer[0];
            appData.masterState = APP_STATE_SPI1_WAIT_FOR_WR_COMPLETION;

            /* Add Master transmit buffer to SPI1 Tx buffer and transmit*/
            appData.drvSPI1TxBufHandle = DRV_SPI_BufferAddWrite(appData.drvSPI1Handle,(SPI_DATA_TYPE *)&drvSPI1TXbuffer[0],
            1 ,APP_BufferEventHandlerSPI1,gBufferContext.SPI1TxBufferRef);

}break;

        case APP_STATE_SPI1_WAIT_FOR_WR_COMPLETION:
        {
            /* Wait till the SPI1 write to slave is over */
            Nop();
        }break;

        case APP_STATE_SPI1_MASTER_IDLE:
        {
            appData.state = APP_STATE_CHECK_DRVR_STATE;
        }break;

        default:
        break;
    }
}

void APP_BufferEventHandlerSPI1(DRV_SPI_BUFFER_EVENT buffEvent,
                            DRV_SPI_BUFFER_HANDLE hBufferEvent,
                            void* context )
{
    switch(buffEvent)
    {
        /* Buffer event is completed successfully. Data is transmitted */
        case DRV_SPI_BUFFER_EVENT_COMPLETE:
        {
            if((context == gBufferContext.SPI1TxBufferRef) &&(appData.masterState == APP_STATE_SPI1_WAIT_FOR_WR_COMPLETION))
            {
                appData.masterState = APP_STATE_SPI1_MASTER_IDLE;
            }
            break;
        }
        default:
            break;
    }
}

Como veis es bastante sencillo, va saltando de estado en estado:
1º: APP_STATE_INIT -> Donde abrimos el SPI.
2º: APP_STATE_CHECK_DRVR_STATE -> comprobamos el estado del SPI y pasamos a trasmitir.
3º: APP_STATE_TRANSFER_DATA_BTWN_MASTER_SLAVE -> Escribimos el byte 0x04 (Incrementar el potenciometro) y esperamos a la interrupción y que acabe de transmitir.

el problema es que solo se manda una sola vez, después ya no puedo volver a mandar nada, a no ser que reinicie el programa, es raro por que segun la documentacion del driver no hace falta cerrar el SPI, si regreso al principio al estado APP_STATE_CHECK_DRVR_STATE sigue el flujo de programa normalmente pero no se manda el dato, sin embargo si lo reinicio del todo, se vuelve a mandar el dato 0x04.

¿Alguien sabe que pasa?

un saludo.
« Última modificación: 08 de Mayo de 2018, 15:31:47 por juaperser1 »
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1900
    • Sicoy
Re:SPI Harmony
« Respuesta #1 en: 22 de Mayo de 2019, 10:25:03 »
Creo que cuando cuando cambias la tarea a este estado:

appData.masterState = APP_STATE_SPI1_WAIT_FOR_WR_COMPLETION;

Y pasar nuevamente a void APP_Tasks ( void ); se ejecuta el estado por defecto:

default:
        {
            break;
        }

Y nunca más vuelves a la función

void APP_SPI_MASTER_Task(void);

Pienso que todos los estados de la tarea deberían estar en  APP_Tasks y debugar para que tu mismo determines hasta donde llega tu código.

Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32