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