#include "stm8l10x_spi.h" #include "stm8l10x_gpio.h" #include "stm8l10x_exti.h" #include "lis3dh.h" #define CS_ON GPIO_ResetBits(GPIOC, GPIO_Pin_3); #define CS_OFF GPIO_SetBits(GPIOC, GPIO_Pin_3); union { volatile u8 regData; TypeDef_CTRL_REG1 reg1; TypeDef_CTRL_REG2 reg2; TypeDef_CTRL_REG3 reg3; TypeDef_CTRL_REG4 reg4; TypeDef_CTRL_REG5 reg5; TypeDef_CTRL_REG6 reg6; TypeDef_FIFO_CTRL_REG regFifoCtrl; TypeDef_FIFO_SRC_REG regFifoSrc; TypeDef_INT1_CFG regInt1Cfg; TypeDef_CLICK_CFG refClickCfg; }reg; #define FIFO_LENGTH (SAMPLE_LENGTH * 32) //160 #define FIFO_MAX (SAMPLE_LENGTH * 30)//150 #define INVALID_LAST_SAMPLE 0xFF #define OVERFLOW_COUNTER 0xFF #define DATA_LENGTH 6 u8 FifoBuffer[FIFO_LENGTH + 1]; u8 SampleBuffer[DATA_LENGTH]; static volatile u8 iFifoRead = 0; static volatile u8 iFifoWrite = 0; static volatile u8 iLastSample = INVALID_LAST_SAMPLE; static volatile u8 nFifoCount = 0; static volatile u8 iFifoCounter = 0; static volatile u8 iExitCode = NO_SAMPLES; static u8 tmpByte; volatile u8 bDataReady = FALSE; volatile u16 CRC16 = 0; const u16 oddparity[] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; extern void ASM_FillFifo(u8* pSample, u8* pFifo); static void LIS3DH_SetRegisterData(u8 reg, u8 data) { reg &= 0x3F; CS_ON; SPI_SendData(reg); while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET); SPI_ReceiveData(); SPI_SendData(data); while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET); SPI_ReceiveData(); CS_OFF; } /* static u8 LIS3DH_GetRegisterData(u8 reg) { u8 data = 0; reg |= 0x80; CS_ON; SPI_SendData(reg); while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET); SPI_ReceiveData(); SPI_SendData(data); while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET); CS_OFF; return SPI_ReceiveData(); } */ static void LIS3DH_GettingDataBytesStart(u8 regStart) { regStart |= 0xC0; CS_ON; SPI_SendData(regStart); while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET); SPI_ReceiveData(); SPI_SendData(0); } static u8 LIS3DH_GetDataByte(u8 bLast) { u8 data = 0; while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET); data = SPI_ReceiveData(); if(bLast) { CS_OFF; } else { SPI_SendData(0); } return data; } /* u8 LIS3DH_GetId(void) { return LIS3DH_GetRegisterData(WHO_AM_I); } */ /* static void LIS3DH_DataRate(u8 ODR) { regData = 0; reg1.Xen = 1; reg1.Yen = 1; reg1.Zen = 1; reg1.ODR = ODR; LIS3DH_SetRegisterData(CTRL_REG1, regData); } */ void LIS3DH_Start(void) { /* regData = 0; reg1.Xen = 1; reg1.Yen = 1; reg1.Zen = 1; reg1.ODR = 3; LIS3DH_SetRegisterData(CTRL_REG1, regData); */ //LIS3DH_DataRate(3); nFifoCount = 0; iFifoCounter = 0; iFifoWrite = 0; iFifoRead = 0; iLastSample = 0; iExitCode = NO_SAMPLES; bDataReady = FALSE; GPIO_Init(GPIOC, GPIO_Pin_4, GPIO_Mode_In_FL_IT); } void LIS3DH_Stop(void) { GPIO_Init(GPIOC, GPIO_Pin_4, GPIO_Mode_In_FL_No_IT); //LIS3DH_DataRate(0); } void LIS3DH_Init(void) { u8 i; reg.regData = 0; reg.reg1.Xen = 1; reg.reg1.Yen = 1; reg.reg1.Zen = 1; reg.reg1.ODR = 3; LIS3DH_SetRegisterData(CTRL_REG1, reg.regData); //LIS3DH_DataRate(0); LIS3DH_SetRegisterData(CTRL_REG2, 0); reg.regData = 0; reg.reg3.I1_DRDY1 = 1; LIS3DH_SetRegisterData(CTRL_REG3, reg.regData); reg.regData = 0; reg.reg4.HR = 1; reg.reg4.BDU = 1; LIS3DH_SetRegisterData(CTRL_REG4, reg.regData); LIS3DH_SetRegisterData(CTRL_REG5, 0); reg.regData = 0; reg.reg6.HL_ACTIVE = 1; LIS3DH_SetRegisterData(CTRL_REG6, reg.regData); LIS3DH_SetRegisterData(INT1_THS, 0); LIS3DH_SetRegisterData(INT1_DURATION, 0); LIS3DH_SetRegisterData(INT1_CFG, 0); LIS3DH_SetRegisterData(FIFO_CTRL_REG, 0); for(i = 0; i < FIFO_LENGTH; i++) { FifoBuffer[i] = 0; } FifoBuffer[i] = 0xA5; } u16 LIS3DH_crc16(u16 data) { data = (data ^ (CRC16 & 0xff)) & 0xff; CRC16 >>= 8; if (oddparity[data & 0xf] ^ oddparity[data >> 4]) CRC16 ^= 0xc001; data <<= 6; CRC16 ^= data; data <<= 1; CRC16 ^= data; return CRC16; } u8 LIS3DH_GetFirstFIFOData(volatile u8 *pcnt) { switch(nFifoCount) { case 0: *pcnt = 1; return NO_SAMPLES; case OVERFLOW_COUNTER: *pcnt = 1; iExitCode = FIFO_OVERFLOW; return iExitCode; } *pcnt = nFifoCount; return FifoBuffer[iFifoRead++]; } u8 LIS3DH_GetNextFIFOData(void) { if(iFifoRead >= FIFO_LENGTH) { iFifoRead = 0; } return FifoBuffer[iFifoRead++]; } u8 LIS3DH_GetFIFODataEnd(void) { if(iFifoRead >= FIFO_LENGTH) { iFifoRead = 0; } nFifoCount = 0; return iExitCode; } /* volatile u8 xl; volatile u8 xh; volatile u8 yl; volatile u8 yh; volatile u8 zl; volatile u8 zh; */ void LIS3DH_DataReady_Handler(void) { while(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4)) { LIS3DH_GettingDataBytesStart(OUT_X_L); SampleBuffer[0] = LIS3DH_GetDataByte(FALSE); SampleBuffer[1] = LIS3DH_GetDataByte(FALSE); SampleBuffer[2] = LIS3DH_GetDataByte(FALSE); SampleBuffer[3] = LIS3DH_GetDataByte(FALSE); SampleBuffer[4] = LIS3DH_GetDataByte(FALSE); SampleBuffer[5] = LIS3DH_GetDataByte(TRUE); LIS3DH_FillFifo(); } /* bDataReady = TRUE; if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4)) { GPIO_Init(GPIOC, GPIO_Pin_4, GPIO_Mode_In_FL_No_IT); bDataReady = FALSE; LIS3DH_Init(); } */ EXTI_ClearITPendingBit(EXTI_IT_Pin4); } void LIS3DH_FillFifo(void) { if(iLastSample != INVALID_LAST_SAMPLE) { tmpByte = FifoBuffer[iLastSample] & 0xF0; FifoBuffer[iLastSample] = tmpByte | NEXT_SAMPLE; } iLastSample = iFifoWrite; ASM_FillFifo(SampleBuffer, &FifoBuffer[iFifoWrite]); /* xl = 0x80; xh = 0x70; yl = yh = 0; zl = 0x80; zh = 0x8F; FifoBuffer[iFifoWrite] = (xl & 0xF0) | LAST_SAMPLE; //X1->fifo FifoBuffer[iFifoWrite + 1] = xh; //X2->fifo, X3->fifo yl >>= 4; xh = yh << 4; yh >>= 4; FifoBuffer[iFifoWrite + 2] = yl | xh;//Y1->fifo, Y2->fifo FifoBuffer[iFifoWrite + 3] = yh | (zl & 0xF0);//Y3, Z1 -> fifo FifoBuffer[iFifoWrite + 4] = zh;//Z2->fifo, Z3->fifo */ iFifoWrite += SAMPLE_LENGTH; if(iFifoWrite >= FIFO_LENGTH) { iFifoWrite = 0; } if(iFifoCounter != OVERFLOW_COUNTER) { iFifoCounter += SAMPLE_LENGTH; } if(nFifoCount == 0) { if(iFifoCounter >= FIFO_MAX) { iFifoCounter = OVERFLOW_COUNTER; nFifoCount = OVERFLOW_COUNTER; } else { nFifoCount = iFifoCounter; iFifoCounter = 0; iLastSample = INVALID_LAST_SAMPLE; } } }