Using Bosch bma2x2 library with SPI

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
TeMa_1467596
Level 5
Level 5
5 sign-ins 5 likes given First like received

I have a design/project using a CYBLE-224116-01 module connected to BMP280 and BMI005 devices on the SPI bus.  Bosch provides a bma2x2 driver that handles these and a bunch of other ICs on GitHub here https://github.com/BoschSensortec/BMA2x2_driver#fileinfo but I'm struggling on the implementation of the SPI driver calls that the user has to insert in bma2x2_support.c starting around line 422 (in the original file), what I have so far is below which is the tail end of the bma2x2_support.c file but I wondered if anyone has already done this or something similar enough to save me a load of time and hassle the lines I've added are commented with // TMXX - thanks in advance for any help.  I realize I'll have to add toggles to take the respective CS# low but that's not a problem for me.

Ted

/* \Brief: The function is used as SPI bus read

* \Return : Status of the SPI read

* \param dev_addr : The device address of the sensor

* \param reg_addr : Address of the first register,

*          will data is going to be read

* \param reg_data : This data read from the sensor,

*          which is hold in an array

* \param cnt : The no of bytes of data to be read */

s8 BMA2x2_SPI_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)

{

s32 iError = BMA2x2_INIT_VALUE;

u8 array[SPI_BUFFER_LEN] = {0xFF};

u8 stringpos;

/* For the SPI mode only 7 bits of register addresses are used.

The MSB of register address is declared the bit what functionality it is

read/write (read as 1/write as 0)*/

array[BMA2x2_INIT_VALUE] = reg_addr|BMA2x2_SPI_BUS_READ_CONTROL_BYTE;

/*read routine is initiated register address is mask with 0x80*/

/*

* Please take the below function as your reference for

* read the data using SPI communication

* " IERROR = SPI_READ_WRITE_STRING(ARRAY, ARRAY, CNT+1)"

* add your SPI read function here

* iError is an return value of SPI read function

* Please select your valid return value

* In the driver SUCCESS defined as 0

* and FAILURE defined as -1

* Note :

* This is a full duplex operation,

* The first read data is discarded, for that extra write operation

* have to be initiated. For that cnt+1 operation done in the SPI read

* and write string function

* For more information please refer data sheet SPI communication:

*/

// TMXX WHAT DO I PUT HERE? It looks like there would need to be a sequence of commands to send out bytes in the out string, discard the first one back, and then store the rest in the second array but again, no status.

for (stringpos = BMA2x2_INIT_VALUE; stringpos < cnt; stringpos++) {

*(reg_data + stringpos) = array[stringpos +

BMA2x2_BUS_READ_WRITE_ARRAY_INDEX];

}

return (s8)iError;

}

/* \Brief: The function is used as SPI bus write

* \Return : Status of the SPI write

* \param dev_addr : The device address of the sensor

* \param reg_addr : Address of the first register,

*               where data is going to be written

* \param reg_data : It is a value hold in the array,

* will be used for write the value into the register

* \param cnt : The no of byte of data to be write

*/

s8 BMA2x2_SPI_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)

{

s32 iError = BMA2x2_INIT_VALUE;

u8 array[SPI_BUFFER_LEN * 2];

u8 stringpos = BMA2x2_INIT_VALUE;

for (stringpos = BMA2x2_INIT_VALUE; stringpos < cnt; stringpos++) {

/* the operation of (reg_addr++)&0x7F done:

because it ensure the

0 and 1 of the given value

It is done only for 8bit operation*/

array[stringpos * 2] = (reg_addr++) &

BMA2x2_SPI_BUS_WRITE_CONTROL_BYTE;

array[stringpos * 2 + BMA2x2_BUS_READ_WRITE_ARRAY_INDEX] =

*(reg_data + stringpos);

}

/* Please take the below function as your reference

* for writing the data using SPI communication

* add your SPI write function here.

* "IERROR = SPI_WRITE_STRING(ARRAY, CNT*2)"

* iError is a return value of SPI write function

* Please select your valid return value

* In the driver SUCCESS defined as 0

     * and FAILURE defined as -1

*/

    SPI_SpiUartPutArray(array, cnt*2); // TM seems to be easy implementation although no status returned

    return 0; // return success

//return (s8)iError;

}

/* Brief : The delay routine

* \param : delay in ms

*/

void BMA2x2_delay_msek(u32 msek)

{

CyDelay(msek); // TMXX convert to Cypress mS delay routine

}

#endif

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ted-san,

(Warning) As I'm very good at making mistakes, please take following with a grain of salt.

Your bmi_spi_read() seems to be OK to me,

except there is no timeout checking,

but bmi_spi_write() seems to be somewhat odd to me.

your code

> do {

>     SPI_SpiUartWriteTxData(reg_addr) ;

>  } while(SPI_SpiUartGetTxBufferSize()) ;

>

> for (i = 0 ; i < length ; i++) {

>     do {

>          SPI_SpiUartWriteTxDat(reg_data) ;

>     } while(SPI_SpiUartGetTxBufferSize()) ;

> }

>

I would write

< // sending address

< SPI_SpiUartWriteTxData(reg_addr) ;

< while(SPI_SpiUartGetTxBufferSize()) {

<    // need to check time out here

<  }

<

> // sending data (pattern1)

> for (i = 0 ; i < length ; i++ ) {

> SPI_SpiUartWriteTxData(reg_data) ;

>     while(SPI_SpiUartGetTxBufferSize()) {

>        // need to check time out here

>     }

> }

or the later half could be

> // sending data (patter2)

> SPI_SpiUartPutArray(reg_data, length) ;

> while(SPI_SpiUartGetTxBufferSize()) {

>    // need to check time out here

>}

In an usual sample, light weight application using "while() ; " would be OK,

but for some critical applications, such as automotive, medical, aero,

dead lock can be fatal.

So usually some time out checking is due where I wrote "// need to check time out here".

There should be many strategies doing it, but for a simple example,

#define SPI_TIME_OUT_MS 500  // you decide the number for your application

...

int timeout_count ;

SPI_SpiUartWriteTxData(reg_data) ;

timeout_count = 0 ;

while(SPI_SpiUartGetTxBufferSize()) {

     timeout_count++ ;

     if (timeout_count >= SPI_TIME_OUT_MS) {

          // this is the place where we set return value to non-zero

          return( 1 ) ; // any non-zero number, you assigned for SPI timeout

     }

    CyDelay(1) ; // wait 1ms

}

Best Regards,

29-Apr-2019

Motoo Tanaka

View solution in original post

0 Likes
11 Replies
GyanC_36
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

Hi Ted,

    I don't think any code example is already available for these sensors to interface with PSoC over SPI but you can make use of available SPI code examples available for PSoC to get more ideas on APIs.

Please refer below code example for the same -

   PSoC-4-BLE/100_Projects_in_100_Days/Day048_SPI_BLE_Bridge at master · cypresssemiconductorco/PSoC-4-...

-Gyan

0 Likes

Gyan,

Thanks, I'll check that out.  I can write my own but didn't want to reinvent the wheel.

Can we leave this thread open for a few days to see if anyone is willing to share code?

Thanks,

Ted

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Last Nov I posted a sample project for BME680 using I2C,

and in my toy box of projects, I found one for BME680 using SPI.

As I left my sensor(bme680) in my office and it's the beginning of 10 days national holiday in Japan, I can not test it if it was working or not, but at least the project is compile-able.

Meantime, skimming the code, I was using just a loop to wait for SPI, if you are creating real application, you need to take care of timeout there.

Having written that attached is my bme680 sample using bosch library and adding my SPI functions.

I hope that at least this can be a hint for you about what kind of APIs to call.

So please don't get mad at me, when the code is not working 😉

following functions are in bme680_user.c

int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)

int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)

moto

This is really bugging me.  I can write SPI drivers and understand the technology of clocking data out and getting it in at the same time.  The Bosh bma2x2 driver has 3 SPI functions that the comments SEEM to suggest that I should be adding code to, the one that's most confusing is the BMA2x2_SPI_bus_read function that's in bma2x2_support.c

/* \Brief: The function is used as SPI bus read

* \Return : Status of the SPI read

* \param dev_addr : The device address of the sensor

* \param reg_addr : Address of the first register,

*          will data is going to be read

* \param reg_data : This data read from the sensor,

*          which is hold in an array

* \param cnt : The no of bytes of data to be read */

s8 BMA2x2_SPI_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)

{

s32 iError = BMA2x2_INIT_VALUE;

u8 array[SPI_BUFFER_LEN] = {0xFF};

u8 stringpos;

/* For the SPI mode only 7 bits of register addresses are used.

The MSB of register address is declared the bit what functionality it is

read/write (read as 1/write as 0)*/

array[BMA2x2_INIT_VALUE] = reg_addr|BMA2x2_SPI_BUS_READ_CONTROL_BYTE;

/*read routine is initiated register address is mask with 0x80*/

/*

* Please take the below function as your reference for

* reading data using SPI communication

* " IERROR = SPI_READ_WRITE_STRING(ARRAY, ARRAY, CNT+1)"

* add your SPI read function here

* iError is an return value of SPI read function

* Please select your valid return value

* In the driver SUCCESS defined as 0

* and FAILURE defined as -1

* Note :

* This is a full duplex operation,

* The first read data is discarded, for that extra write operation

* have to be initiated. For that cnt+1 operation done in the SPI read

* and write string function

* For more information please refer data sheet SPI communication:

*/

WHAT TO PUT IN HERE???

   

for (stringpos = BMA2x2_INIT_VALUE; stringpos < cnt; stringpos++) {

*(reg_data + stringpos) = array[stringpos +

BMA2x2_BUS_READ_WRITE_ARRAY_INDEX];

}

return (s8)iError;

}

I sort of get that, after setting the right CS low, I'd do something like..

SPI_SpiUartWriteTxData(array[0]);

and then I could write...

array[0] = SPI_SpiUartReadRxData();

Obviously I'd do that with a loop but what's confusing me is that they seem to want me to write out and read in the same array, is that what they really want?

In this link BMF055-flight-controller/bma2x2_support.c at master · NightHawk32/BMF055-flight-controller · GitHub starting at line 118 they seem to have tackled the same subject but the code provided in the Bosch driver at the end...

for (stringpos = BMA2x2_INIT_VALUE; stringpos < cnt; stringpos++) {

*(reg_data + stringpos) = array[stringpos +

BMA2x2_BUS_READ_WRITE_ARRAY_INDEX];

}

return (s8)iError;

}

Seems to have been deleted and I don't see where they put the returned bytes into the array?

HELP!

0 Likes

Now I'm beginning to wonder whether I'm over complicating this. maybe the Bosch suggestion of...

" IERROR = SPI_READ_WRITE_STRING(ARRAY, ARRAY, CNT+1)"

Is a typo, I think they meant...

" IERROR = SPI_READ_WRITE_STRING(ADDRESS, ARRAY, CNT+1)"

That would explain my first concern but still leaves the question of what that last bit of code does?

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ted-san,

I think

   "IERROR = SPI_READ_WRITE_STRING(ARRAY, ARRAY, CNT+1) "

is correct, since they filled the first byte

   array[BMA2x2_INIT_VALUE] = reg_addr | BMA2x2_SPI_BUS_READ_CONTROL_BYTE;

BTW, I don't understand why they use BMA2x2_INIT_VALUE for both return value and array index.

Meantime, since the array is instantiated at the beginning of this function,

having offset for the array does not make sense.

So if I interpret BMA2x2_INIT_VALUE as 0, then I can read that they fill the first byte for address to read,

then the remaining CNT bytes are for clocking out the result and receiving it to the same array.

(I don't like this strategy though).

I'd rather write something like

iError = SPI_READ_WRITE_STRING(tx_buffer, rx_buffer, CNT+1) ;

so that debugging will be easier.

Anyway I think that the intention of s8 BMA2x2_SPI_bus_read() is

(1) Sending read request for the reg_addr

(2) Receiving cnt bytes to reg_data[]

And if any of PSoC SPI API returns error/failure, set iError to non zero value.

Best Regards,

28-Apr-2019

Motoo Tanaka

Moto-san,

Thanks so much for your help, I work on my own and it's difficult to get my mind straight when I read code that seems not to be doing something logical.

I've decided to try to adapt the code in this link BMF055-flight-controller/bma2x2_support.c at master · NightHawk32/BMF055-flight-controller · GitHub into my project and convert the Atmel? SPI calls to something equivalent in PSoC GCC.  I'll let you know how I get on but I'm having cataract eye surgery tomorrow so I may not be around for a few days.

Thanks for helping during your holiday, hope you're having a nice rest.

Ted Mawson

0 Likes

All my SPI calls e.g.

SPI_SpiUartWriteTxData(dataToSend);

Don't return a stats value to say if the SPI action was successful.  The bma2x2 code assumes that there's some kind of iError parameter that is set to 0 if all is good.  Is there a way to read a status register or flag to find out if the last SPI transaction was dowe without error?

0 Likes

I haven't tried it yet as I need to write a test function to see values streaming but here is the updated bma2x2_support.c file

/**

*

*

**************************************************************************

* Copyright (C) 2015 Bosch Sensortec GmbH. All Rights Reserved.

*

* File: bma2x2_support.c

*

* Date: 2015/02/02

*

* Revision: 1.0

*

* Usage: Part of BMF055 Data Stream Project

*

**************************************************************************

* \section License

*

* Redistribution and use in source and binary forms, with or without

* modification, are permitted provided that the following conditions are met:

*

*   Redistributions of source code must retain the above copyright

*   notice, this list of conditions and the following disclaimer.

*

*   Redistributions in binary form must reproduce the above copyright

*   notice, this list of conditions and the following disclaimer in the

*   documentation and/or other materials provided with the distribution.

*

*   Neither the name of the copyright holder nor the names of the

*   contributors may be used to endorse or promote products derived from

*   this software without specific prior written permission.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND

* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR

* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

* DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER

* OR CONTRIBUTORS BE LIABLE FOR ANY

* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,

* OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,

* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN

* ANY WAY OUT OF THE USE OF THIS

* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE

*

* The information provided is believed to be accurate and reliable.

* The copyright holder assumes no responsibility

* for the consequences of use

* of such information nor for any infringement of patents or

* other rights of third parties which may result from its use.

* No license is granted by implication or otherwise under any patent or

* patent rights of the copyright holder.

*

*

*************************************************************************/

/*!

*

* @file bma2x2_support.c

* @author Bosch Sensortec

*

* @brief Functions declared in bma2x2_support.h file are defined here.

*

*

*/

/************************************************************************/

/* Include Own Header                                                   */

/************************************************************************/

#include <project.h>

#include <bma2x2_support.h>

/************************************************************************/

/* Function Definitions                                                 */

/************************************************************************/

/*!

* @brief Initializes BMA280 accelerometer sensor and its required connections

*

* @param [in] NULL

*

* @param [out] NULL

*

* @return NULL

*

*/

void bma_init(void)

{

/* Configure an SPI slave instance for the sensor */

  //spi_configure_slave(&bma2x2_spi_slave, BMA2x2_SS_PIN); TMXXX

    /* Assign functions required by sensor API */

bma2x2.bus_write = &bma_spi_write;

bma2x2.bus_read = &bma_spi_read;

bma2x2.delay_msec = &bma_delay_msec;

/* Call sensor API initialization function */

bma2x2_init(&bma2x2);

}

/*!

* @brief Sends data to BMA280 via SPI

*

* @param[in] dev_addr Device I2C slave address (not used)

*

* @param[in] reg_addr Address of destination register

*

* @param[in] reg_data Pointer to data buffer to be sent

*

* @param[in] length Length of the data to be sent

*

* @retval 0 BMA2x2_SUCCESS

* @retval -1 BMA2x2_ERROR

*

*/

int8_t bma_spi_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t length)

{

  // enum status_code bma_write_stat = STATUS_NO_CHANGE; //TMXX4

    (void) dev_addr ;

    uint16_t i ;

    SPI_SpiUartClearTxBuffer();

    SPI_SpiUartClearRxBuffer();

   

ACC_CS_Write(0);

    CyDelayUs(10) ;

   

    do {

        SPI_SpiUartWriteTxData(reg_addr);

    } while(SPI_SpiUartGetTxBufferSize());

   

    for (i = 0 ; i < length ; i++ ) {

        do {

            SPI_SpiUartWriteTxData(reg_data) ;

        } while(SPI_SpiUartGetTxBufferSize());

    }

    while(!SPI_SpiIsBusBusy()) {

        ;   // TMXX4 wait for SPI to complete

    }

    SPI_SpiUartClearRxBuffer(); // TMXX4 throw away junk received bytes

   

ACC_CS_Write(1);

return 0;       // TMXX4 for now, just return sucess

}

/*!

* @brief Receives data from BMA280 on SPI

*

* @param[in] dev_addr Device I2C slave address (not used)

*

* @param[in] reg_addr Address of destination register

*

* @param[out] reg_data Pointer to data buffer to be received

*

* @param[in] length Length of the data to be received

*

* @retval 0 BMA2x2_SUCCESS

* @retval -1 BMA2x2_ERROR

*

*/

int8_t bma_spi_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *rx_data, uint8_t length)

{

// enum status_code bma_read_stat = STATUS_NO_CHANGE;

    (void) dev_addr ;

    uint16_t i ;   

    SPI_SpiUartClearTxBuffer();

    SPI_SpiUartClearRxBuffer();

   

    ACC_CS_Write(0);

    CyDelayUs(10) ;

   

    SPI_SpiUartWriteTxData(0x80 | reg_addr) ;

    while(SPI_SpiUartGetRxBufferSize() < 1) {

        ;

    }

    rx_data[0] = SPI_SpiUartReadRxData() ;      // read dummy byte

    for (i = 0 ; i < length ; i++ ) {

        SPI_SpiUartWriteTxData(0x80 | (reg_addr+i)) ;

        while(SPI_SpiUartGetTxBufferSize()) {

            ;

        }

        while(SPI_SpiUartGetRxBufferSize() < 1) {

            ;

        }

        rx_data = SPI_SpiUartReadRxData() ;

    }

    ACC_CS_Write(1) ;

return 0;

}

/*!

* @brief Initiates a delay of the length of the argument in milliseconds

*

* @param[in] msec Delay length in terms of milliseconds

*

* @param[out] NULL

*

* @return NULL

*

*/

void bma_delay_msec(uint32_t msec)

{

CyDelay(msec);

}

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Ted-san,

(Warning) As I'm very good at making mistakes, please take following with a grain of salt.

Your bmi_spi_read() seems to be OK to me,

except there is no timeout checking,

but bmi_spi_write() seems to be somewhat odd to me.

your code

> do {

>     SPI_SpiUartWriteTxData(reg_addr) ;

>  } while(SPI_SpiUartGetTxBufferSize()) ;

>

> for (i = 0 ; i < length ; i++) {

>     do {

>          SPI_SpiUartWriteTxDat(reg_data) ;

>     } while(SPI_SpiUartGetTxBufferSize()) ;

> }

>

I would write

< // sending address

< SPI_SpiUartWriteTxData(reg_addr) ;

< while(SPI_SpiUartGetTxBufferSize()) {

<    // need to check time out here

<  }

<

> // sending data (pattern1)

> for (i = 0 ; i < length ; i++ ) {

> SPI_SpiUartWriteTxData(reg_data) ;

>     while(SPI_SpiUartGetTxBufferSize()) {

>        // need to check time out here

>     }

> }

or the later half could be

> // sending data (patter2)

> SPI_SpiUartPutArray(reg_data, length) ;

> while(SPI_SpiUartGetTxBufferSize()) {

>    // need to check time out here

>}

In an usual sample, light weight application using "while() ; " would be OK,

but for some critical applications, such as automotive, medical, aero,

dead lock can be fatal.

So usually some time out checking is due where I wrote "// need to check time out here".

There should be many strategies doing it, but for a simple example,

#define SPI_TIME_OUT_MS 500  // you decide the number for your application

...

int timeout_count ;

SPI_SpiUartWriteTxData(reg_data) ;

timeout_count = 0 ;

while(SPI_SpiUartGetTxBufferSize()) {

     timeout_count++ ;

     if (timeout_count >= SPI_TIME_OUT_MS) {

          // this is the place where we set return value to non-zero

          return( 1 ) ; // any non-zero number, you assigned for SPI timeout

     }

    CyDelay(1) ; // wait 1ms

}

Best Regards,

29-Apr-2019

Motoo Tanaka

0 Likes

OK, I finally got round to working on this and have been successful, mostly thanks to Motoo Tanaka.

The code I ended up with for the SPI read and write functions is below; there's a weird part of the read where it appears that the dummy data from the sending of the reg_addr is included in index 0 of the returned array; the ADC values that come back from the accelerometer all look fine though.  I'm not quite clear how to set the parameters in the bma2x2 structure variable but I'll experiment.

Thanks to all who contributed.

Ted M

/************************************************************************/

/* Function Definitions                                                 */

/************************************************************************/

/*!

* @brief Initializes BMA280 accelerometer sensor and its required connections

*

* @param [in] NULL

*

* @param [out] NULL

*

* @return NULL

*

*/

void bma_init(void)

{

/* Configure an SPI slave instance for the sensor */

  //spi_configure_slave(&bma2x2_spi_slave, BMA2x2_SS_PIN); TMXXX

    /* Assign functions required by sensor API */

bma2x2.bus_write = &bma_spi_write;

bma2x2.bus_read = &bma_spi_read;

bma2x2.delay_msec = &bma_delay_msec;

/* Call sensor API initialization function */

bma2x2_init(&bma2x2);

}

/*!

* @brief Sends data to BMA280 via SPI

*

* @param[in] dev_addr Device I2C slave address (not used)

*

* @param[in] reg_addr Address of destination register

*

* @param[in] reg_data Pointer to data buffer to be sent

*

* @param[in] length Length of the data to be sent

*

* @retval 0 BMA2x2_SUCCESS

* @retval -1 BMA2x2_ERROR

*

*/

int8_t bma_spi_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t length)

{

  // enum status_code bma_write_stat = STATUS_NO_CHANGE; //TMXX4

    (void) dev_addr ;

    uint16_t i ;

    int timeout_count;

   

ACC_CS_Write(0);

    CyDelayUs(10) ;

    SPI_SpiUartClearTxBuffer();

    SPI_SpiUartClearRxBuffer();

   

    SPI_SpiUartWriteTxData(reg_addr);       // send out the register address

    timeout_count = 0;

    while(SPI_SpiUartGetTxBufferSize()) {   // wait until TX buffer is empty

        timeout_count++;

        if (timeout_count >= SPI_TIME_OUT_MS) {

            return (1);   // any non-zero number, you assigned for SPI timeout

        }

    }

   

    SPI_SpiUartClearTxBuffer();             // this is a write function so...

    SPI_SpiUartClearRxBuffer();             // discard any RXd data

   

    for (i = 0 ; i < length ; i++ ) {

        SPI_SpiUartWriteTxData(reg_data) ;

        while(SPI_SpiUartGetTxBufferSize()) {   // wait until TX buffer is empty

            timeout_count++;

            if (timeout_count >= SPI_TIME_OUT_MS) {

                return (1);                 // any non-zero number, you assigned for SPI timeout

            }

        }

    }

    SPI_SpiUartClearTxBuffer();             // this is a write function so...

    SPI_SpiUartClearRxBuffer();             // discard any RXd data

   

ACC_CS_Write(1);

return (0);       // TMXX4 return sucess

}

/*!

* @brief Receives data from BMA280 on SPI

*

* @param[in] dev_addr Device I2C slave address (not used)

*

* @param[in] reg_addr Address of destination register

*

* @param[out] reg_data Pointer to data buffer to be received

*

* @param[in] length Length of the data to be received

*

* @retval 0 BMA2x2_SUCCESS

* @retval -1 BMA2x2_ERROR

*

*/

int8_t bma_spi_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *rx_data, uint8_t length)

{

// enum status_code bma_read_stat = STATUS_NO_CHANGE;

    (void) dev_addr ;

    uint16_t i ;

    int timeout_count;

   

    ACC_CS_Write(0);

    CyDelayUs(10) ;

   

    SPI_SpiUartClearTxBuffer();

    SPI_SpiUartClearRxBuffer();   

   

    SPI_SpiUartWriteTxData(0x80 | reg_addr) ;

    timeout_count = 0;

    while(SPI_SpiUartGetRxBufferSize() < 1) {

        timeout_count++;

        if (timeout_count >= SPI_TIME_OUT_MS) {

            return (1);   // any non-zero number, you assigned for SPI timeout

        }

    }

    rx_data[0] = SPI_SpiUartReadRxData() ;      // read dummy byte (we'll overwrite in a moment)

    for (i = 0 ; i < length ; i++ ) {

        SPI_SpiUartWriteTxData(0x80 | (reg_addr+i));   // suspicious that the dummy byte is stil there in xxx[0]

        timeout_count = 0;

        while(SPI_SpiUartGetTxBufferSize()) {

            timeout_count++;

            if (timeout_count >= SPI_TIME_OUT_MS) {

                return (1);   // any non-zero number, you assigned for SPI timeout

            }

        }

        timeout_count = 0;

        while(SPI_SpiUartGetRxBufferSize() < 1) {

            timeout_count++;

            if (timeout_count >= SPI_TIME_OUT_MS) {

                return (1);   // any non-zero number, you assigned for SPI timeout

            }

        }

        rx_data = SPI_SpiUartReadRxData() ;

    }

    ACC_CS_Write(1) ;

return 0;

}

/*!

* @brief Initiates a delay of the length of the argument in milliseconds

*

* @param[in] msec Delay length in terms of milliseconds

*

* @param[out] NULL

*

* @return NULL

*

*/

void bma_delay_msec(uint32_t msec)

{

CyDelay(msec);

}

0 Likes