This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BLE Stack 1.4 hal_spi.h missing?

Other Parts Discussed in Thread: BLE-STACK, CC2540

Hello,

I got a problem here: I'm working with the stack 1.4 with a modificated version of the Peripheral Profile Demo Project. Now I wanted to use the SPI Interface provided by HAL. So, I added the preprocessor macros:

HAL_SPI=TRUE
HAL_UART_SPI=1
HAL_SPI_MASTER

But when I try to compile my project, the file "hal_spi.h" could not be found. I checked in the folder where I installed the BLE stack, but I can't find it anywhere. Can you provide this file for me, or do I have to write it myself using the functions from "_hal_uart_spi.c"? Please point me to the solution.


Best regards

Karl

  • Hey Karl,

    I believe that HAL_SPI is an old macro. You should only use HAL_UART_SPI=1 and HAL_SPI_MASTER to configure the USART driver. There is a SPI guide that might be useful about half way down this post (http://e2e.ti.com/support/wireless_connectivity/f/538/t/334735.aspx) by Joakim.

    -Matt

  • Hi Matt,

    thank you for your reply. I'll try it first thing in the morning, it's kind of late here in Austria :-)

    Best regards

    Karl

  • Karl Osterseher said:

    ... I'll try it first thing in the morning ...

    Hello again,

    the mentioned macro was really an old one, with HAL_UART_SPI the driver can be used!


    But, when I try to write data with SPI through DMA only the first Byte gets sent. Now I tried to write my own driver for SPI, which works fine without the usage of the DMA module or Interrupts. Now I want to use the DMA module to generate a clk (without pauses) on the SCK line for a continous stream of data between master and slave. My code is the following:

    void tuInitSpi(void) {
      uint8 statusByte = 0x00;
      uint8 hwEoWrtDetDis = SST_DBSY;
      uint8 writeDisable = SST_WRDI;
    
      // configure the pins for SPI mode
      cbPIO_open(cbPIO_PORT_0, cbPIO_PIN_5, NULL, tuPIO_NONE, cbPIO_ALTERNATE, cbPIO_LOW);        //SCK
      cbPIO_open(cbPIO_PORT_0, cbPIO_PIN_3, NULL, tuPIO_NONE, cbPIO_ALTERNATE, cbPIO_LOW);        //MOSI
      cbPIO_open(cbPIO_PORT_0, cbPIO_PIN_2, NULL, tuPIO_NONE, cbPIO_ALTERNATE, cbPIO_LOW);        //MISO
      
      // pins for controling the SST Flash
      cbPIO_open(cbPIO_PORT_0, cbPIO_PIN_4, NULL, tuPIO_NONE, cbPIO_OUTPUT, cbPIO_HIGH);          //CSn
      cbPIO_open(cbPIO_PORT_0, cbPIO_PIN_6, NULL, tuPIO_NONE, cbPIO_OUTPUT, cbPIO_HIGH);          //HOLDn
      
      //configure SPI master mode
      PERCFG &= ~HAL_UART_PERCFG_BIT;    /* Set UART0 I/O to Alt. 1 location on P0 */
    
      U0CSR = 0;                         /* Mode is SPI-Master Mode */
      U0GCR =  BAUD_E;                   /* Cfg for the max Rx/Tx baud of 4-MHz */
      U0BAUD = BAUD_M;
    
      U0UCR = UCR_FLUSH;                 /* Flush it */
      U0GCR |= BV(5);                    /* Set bit order to MSB first, Data centered on 
                                            first edge of SCK period, SCK low when idle */
    
      P2DIR &= ~P2DIR_PRIPO;        // USART0 has highest priority on the assigned pins
      
      // disable HW end of write detection first! Could have been enabled at some previous point
      CSn = 0;
      tuSndDataSpiBlocking(&writeDisable, 1);
      CSn = 1;  
      
      Hal_HW_Wait1ClkCy();
        
      CSn = 0;
      tuSndDataSpiBlocking(&hwEoWrtDetDis, 1);
      CSn = 1;  
      
      Hal_HW_Wait1ClkCy();
      
      // now clear the block protection (BP3,BP2, BP1, BP0)
      while ( !tuWriteStatusReg(&statusByte) );      //and wait if not written correct, for debugging 
    }
    void tuInitSpiDMA(void) {
      
      halDMADesc_t *ch;
    
      /* Fill in DMA channel 3 descriptor and define it as output */
      ch = HAL_DMA_GET_DESC1234( HAL_DMA_SPI_OUT ); // HAL_DMA_SPI_OUT= 3
      
      /* Abort any pending DMA operations (in case of a soft reset) */
      HAL_DMA_ABORT_CH( HAL_DMA_SPI_OUT );  
      
      HAL_DMA_SET_SOURCE( ch, txBufferMaster );           /* Start address of the segment */
      HAL_DMA_SET_DEST( ch, HAL_DMA_U0DBUF );                       /* start address of the segment */
      HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN );         /* Using the length field */
      HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE );   /* One byte is transferred each time */
      HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE );    /* A single byte is transferred each time */
      HAL_DMA_SET_TRIG_SRC( ch, HAL_DMA_TRIG_UTX0 );      /* Tx Complete trigger */
      HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 );          /* The address for data fetch is constant */
      HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 );          /* The destination address is incremented by 1 byte */
      HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE );       /* The DMA complete interrupt flag is set at completion */
      HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS );          /* Transferring all 8 bits in each byte */
      HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH );         /* DMA has priority */
      
      //---------------------------------------------------------------------------------
      //---------------------------------------------------------------------------------
      // 1. Clear interrupt flags
      // For pulsed or edge shaped interrupt sources one should clear the CPU interrupt
      // flag prior to clearing the module interrupt flag
      DMAIF = 0;
      DMAIRQ &= ~DMAIF3;
      // 2. Set individual interrupt enable bit in the peripherals SFR, if any
      // No flag for the DMA (Set in the DMA struct (IRQMASK = 1))
      // 3. Set the corresponding individual, interrupt enable bit in the IEN0, IEN1, or
      // IEN2 registers to 1
      DMAIE = 1;  
    }
    void tuStartDMAtransfer(void) {
      halDMADesc_t *ch = HAL_DMA_GET_DESC1234(HAL_DMA_SPI_OUT);
      HAL_DMA_SET_LEN(ch, 10); 
     
      /* Abort any pending DMA operations */
      HAL_DMA_ABORT_CH( HAL_DMA_SPI_OUT );
      HAL_DMA_ARM_CH(HAL_DMA_SPI_OUT);
    
      asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
      asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");
      
      CSn = 0;
      
      HAL_DMA_MAN_TRIGGER( HAL_DMA_SPI_OUT );
      while (1) {
        
        if (mDataTransmitted)
        {
          CSn = HIGH; // All 10 bytes are sent so SSN is pulled high again
          mDataTransmitted = FALSE;
          break;
        }
        
        // Implement code to execute while waiting for the 10 bytes to be transmitted
        // .
        // .
        // .
      }  
    }
    //---------------------------------------------------------------------------------
    #pragma vector=DMA_VECTOR
    __interrupt void dma_IRQ(void)
    {
      DMAIF = 0; // Clear the CPU DMA interrupt flag
      DMAIRQ &= ~DMAIF3; // DMA channel 0 module interrupt flag
      while (U0CSR & U0ACTIVE_BIT); // Wait for the transfer to complete (the last byte
      // transfer is not complete even if transfer count is
      // reached)
      mDataTransmitted = TRUE; // All 10 bytes are transmitted
    }
    //---------------------------------------------------------------------------------

    I used DN113 (http://www.ti.com/lit/an/swra223a/swra223a.pdf) as a reference, but when I call my function tuStartDMAtransfer(); the first Byte gets sent and after that it hangs in the while(1) part. Seems like there are no trigger events generated?! What I'm doing wrong?

    My Preprocessor Macros in BLE-Stack v1.3 are:
    INT_HEAP_LEN=3000
    HALNODEBUG
    OSAL_CBTIMER_NUM_TASKS=1
    HAL_AES_DMA=TRUE
    POWER_SAVING
    HAL_LCD=FALSE
    HAL_LED=FALSE
    HAL_KEY=FALSE
    CC2540_MINIDK
    NO_BLS_ESCAPE_DETECTION
    NO_BLS_WATCHDOGS
    HAL_DMA=TRUE

    Best regards

    Karl

    EDIT: so i found my mistake. After not working on this part of my project for quite a while now, i had a look on my code again and found the one line where i did wrong.

      HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 );          /* The destination address is incremented by 1 byte */


    This should be

      HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 );          /* The destination address is NOT incremented*/


    now it works like it's supposed to!