Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ARM CMSIS SPI without RTOS

Status
Not open for further replies.

dizgah

Member level 5
Joined
Nov 8, 2009
Messages
91
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
iran-8par
Activity points
2,049
I'm trying to drive SPI peripheral of my LPC17xx MCU with the latest CMSIS libraries(CMSIS-Driver Version 2.03). I am using its example code described in the SPI Interface. The example used RTOS for driving but I want to use it in bare metal state & because of it I must find a alter for line:
Code:
osEvent evt;
that defined an evt structure in the RTX,which used to notify the events. as you know CMSIS libraries in this version has comprehensive changes & therefor earlier versions tutorial are not useful.

Example Code:
Code:
#include "Driver_SPI.h"

#include "cmsis_os.h"                   // ARM::CMSIS:RTOS:Keil RTX




void mySPI_Thread(void const *argument);

osThreadId tid_mySPI_Thread;


/* SPI Driver */

extern ARM_DRIVER_SPI Driver_SPI0;


void mySPI_callback(uint32_t event)
{
    switch (event)
    {
    case ARM_SPI_EVENT_TRANSFER_COMPLETE:
                          /* Success: Wakeup Thread */
        osSignalSet(tid_mySPI_Thread, 0x01);
        break;
    case ARM_SPI_EVENT_DATA_LOST:
        /*  Occurs in slave mode when data is requested/sent by master
            but send/receive/transfer operation has not been started
            and indicates that data is lost. */
                    __breakpoint(0);  /* Error: Call debugger or replace with custom error handling */
        break;
    case ARM_SPI_EVENT_MODE_FAULT:
        /*  Occurs in master mode when Slave Select is deactivated and
            indicates Master Mode Fault. */
                    __breakpoint(0);  /* Error: Call debugger or replace with custom error handling */
        break;
    }
}

/* Test data buffers */
const uint8_t testdata_out[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; 
uint8_t       testdata_in [8];

void mySPI_Thread(void const* arg)
{
    ARM_DRIVER_SPI* SPIdrv = &Driver_SPI0;
          osEvent evt;

#ifdef DEBUG
    ARM_DRIVER_VERSION   version;
    ARM_SPI_CAPABILITIES drv_capabilities;

    version = SPIdrv->GetVersion();
    if (version.api < 0x200) /* requires at minimum API version 2.00 or higher */
    {                        /* error handling                                 */
        return;
    }

    drv_capabilities = SPIdrv->GetCapabilities();
    if (drv_capabilities.event_mode_fault == 0)
    {                        /* error handling */
        return;
    }
#endif

    /* Initialize the SPI driver */
    SPIdrv->Initialize(mySPI_callback);
    /* Power up the SPI peripheral */
    SPIdrv->PowerControl(ARM_POWER_FULL);
    /* Configure the SPI to Master, 8-bit mode @10000 kBits/sec */
    SPIdrv->Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL1_CPHA1 | ARM_SPI_MSB_LSB | ARM_SPI_SS_MASTER_SW | ARM_SPI_DATA_BITS(8), 10000000);

    /* SS line = INACTIVE = HIGH */
    SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_INACTIVE);

    /* thread loop */
    while (1)
    {
        /* SS line = ACTIVE = LOW */
        SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_ACTIVE);
        /* Transmit some data */
        SPIdrv->Send(testdata_out, sizeof(testdata_out));
        /* Wait for completion */
        evt = osSignalWait(0x01, 100);
        if (evt.status == osEventTimeout) {
            __breakpoint(0); /* Timeout error: Call debugger */
        }
        /* SS line = INACTIVE = HIGH */
        SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_INACTIVE);
        /* SS line = ACTIVE = LOW */
        SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_ACTIVE);
        /* Receive 8 bytes of reply */
        SPIdrv->Receive(testdata_in, 8);
        evt = osSignalWait(0x01, 100);
        if (evt.status == osEventTimeout) {
            __breakpoint(0); /* Timeout error: Call debugger */
        }
        /* SS line = INACTIVE = HIGH */
        SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_INACTIVE);
    }
}
My other question is about this type of programming? I am familiar with structures or pointers but I cannot understand why don't they use simple function in normal instead of :
Code:
extern ARM_DRIVER_SPI Driver_SPI0;
ARM_DRIVER_SPI* SPIdrv = &Driver_SPI0;
SPIdrv->Send(testdata_out, sizeof(testdata_out));
As I said I can understand what above codes do ,but I can't understand why don't they use them in usual mode? for example:
Code:
int32_t ARM_SPI_Send    (   const void *    data,   uint32_t    num )
WBR.
 

My other question is about this type of programming? I am familiar with structures or pointers but I cannot understand why don't they use simple function

It's the C++ way of handling things. I agree that it's not necessarily advantageous for a "casual" C-programmer, but it can improve clarity and comprehensibility of large projects.

If you don't rely on asynchronous operation of the SPI interface in a multi-threading environment, it's probably easier to write a few low level functions for direct SPI interface access.
 
  • Like
Reactions: dizgah

    dizgah

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top