STM32 SPI Library for AS5048 Magnetic Rotary Encoder

STM32 SPI Library for AS5048 Magnetic Rotary Encoder 

Please read Liability Disclaimer and License Agreement CAREFULLY

Before going further, please read AS5048 datasheet.

AS5048.h

#ifndef __AS5048_H
#define __AS5048_H

#ifdef __cplusplus
extern "C" {
#endif
#include "spi.h"
//Control and Error Registers
//#define SPI_CMD_READ        0x4000 // flag indicating read attempt
#define SPI_CMD_WRITE        0x8000 // flag indicating write attempt
#define SPI_NOP                0x0000//B0000000000000000 No operation dummy information
#define SPI_REG_AGC            0x7ffd // agc register when using SPI 
#define SPI_REG_MAG            0x7ffe // magnitude register when using SPI
#define SPI_REG_DATA        0xffff // data register when using SPI
#define SPI_REG_CLRERR        0x4001 // clear error register when using SPI
#define SPI_REG_ZEROPOS_HI    0x0016 // zero position register high byte
#define SPI_REG_ ZEROPOS_LO    0x0017 // zero position register low byte
#define AS5048_Max            16383
#define AS5048_Magic        (16384 - 31 - 1)    
#define DPU                    0.02197265625//Deg per 14bit unit
#define AS_Count            3//4 sensors attached to SPI2 
    
typedef struct {
    uint8_t Id;    
    uint16_t CrtValue;
    uint16_t PrevValue;
    uint8_t Fault; //handle by interrupt

} myAS5048;
    uint16_t AS5048_getRelativeValue(uint8_t sensor);
    uint16_t AS5048_getValue(uint8_t sensor);
    uint16_t AS5048_getMagnitude(uint8_t sen);
    uint16_t AS5048_getDiagnostics(uint8_t sen);
    uint16_t AS5048_getError(uint8_t sen);
    uint8_t AS5048_getErrFlag(uint8_t sen);
    
#ifdef __cplusplus
}
#endif

#endif /* __AS5048_H */

AS5048.c

Check below example for Chip Select pin toogle

#define ResistorOn HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
#define ResistorOff HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);

In spi.h file i have defined the following maros to change the SPI settings

#define SPI_Default hspi2.Instance->CR1 = 0x0000031F
#define SPI_AS5048  hspi2.Instance->CR1 = 0x0000031C
#define SPI_SPEED_H hspi2.Instance->CR1 = 0x0000030F

 

#include "AS5048.h"
#include "spi.h"
#include "gpio.h"

static uint8_t AS5048_Error[4] = {0, 0, 0, 0};
static uint16_t AS5048_CrtVal[4] = {0, 0, 0, 0};
static uint16_t AS5048_OldVal[4] = {0, 0, 0, 0};

static void set_CS(uint8_t senPin, uint8_t state){
    if(state)    {
        switch(senPin){
            case 0:
                H_S1CS_Release;
            break;
            case 1:
                H_S2CS_Release;
            break;
            case 2:
                V_S1CS_Release;
            break;
            case 3:
                V_S2CS_Release;
            break;
        }
    }
    else {
        switch(senPin) {
            case 0:
                H_S1CS_Select;
            break;
            case 1:
                H_S2CS_Select;
            break;
            case 2:
                V_S1CS_Select;
            break;
            case 3:
                V_S2CS_Select;
            break;
        }
    }
    for(uint8_t i = 0;i < 200; i++);//short delay for CS toogle
}

static uint16_t read(uint8_t sen, uint16_t registerAddress){
    SPI_AS5048;//Set SPI2->CR1-->CPOL Low
    uint8_t data[2] = {0, 0};
    uint8_t cmd[2] = {0, 0};
    //Split the command into two uint8_t
    cmd[1] = registerAddress & 0xFF;
    cmd[0] = ( registerAddress >> 8 ) & 0xFF;
    //printf("data[0] = %d data[1] = %d \n", data[0], data[1]);
    //Send the command
    set_CS(sen, 0);
    HAL_SPI_Transmit(&hspi2, cmd, 2, 1000);
    set_CS(sen, 1);
    //Now read the response
    set_CS(sen, 0);
    HAL_SPI_TransmitReceive(&hspi2, cmd, data, 4, 1000);
    set_CS(sen, 1);
    //printf("data[0] = %d data[1] = %d \n", data[0], data[1]);
    //Check if the error bit is set
    if (data[0] & 0x40) {
        //printf("I have error \n");
        AS5048_Error[sen] = 1;
    }
    else {
        AS5048_Error[sen] = 0;
    }
    SPI_Default;//Set SPI2->CR1-->CPHA High
    //Return the data, stripping the parity and error bits
    return ((( data[0] & 0xFF) << 8) | (data[1] & 0xFF)) & ~0xC000;
}

uint16_t AS5048_getRelativeValue(uint8_t sensor){
    int16_t tmpVal = 0;
    AS5048_OldVal[sensor] = AS5048_CrtVal[sensor];
    AS5048_CrtVal[sensor] = read(sensor,SPI_REG_DATA);
    tmpVal = AS5048_CrtVal[sensor] - AS5048_OldVal[sensor];
    if(tmpVal < 0){
        return AS5048_CrtVal[sensor] + (AS5048_Max - AS5048_OldVal[sensor]);
    } else {
        return tmpVal;
    }
}

uint16_t AS5048_getValue(uint8_t sensor){
    return read(sensor,SPI_REG_DATA);
}

uint16_t AS5048_getMagnitude(uint8_t sen){
    return read(sen, SPI_REG_MAG);//Received data is thrown away: this data comes from the precedent command (unknown)
}
uint16_t AS5048_getDiagnostics(uint8_t sen){
    return read(sen, SPI_REG_AGC);//Received data is thrown away: this data comes from the precedent command (unknown)
}

uint16_t AS5048_getError(uint8_t sen){
    return read(sen, SPI_REG_CLRERR);//Received data is thrown away: this data comes from the precedent command (unknown)
}

uint8_t AS5048_getErrFlag(uint8_t sen){
    return AS5048_Error[sen];
}

 

Comments powered by CComment

Who’s online

We have 354 guests and no members online