#include "stm8l10x.h" #include "stm8l10x_spi.h" #include "stm8l10x_exti.h" #include "stm8l10x_tim2.h" #include "stm8l10x_tim3.h" #include "stm8l10x_tim4.h" #include "stm8l10x_itc.h" #include "lis3dh.h" #include "eeprom.h" #include "watchdog.h" #include "main.h" #ifdef _SDCC_ #include "interupt.h" #endif volatile u8 mode = WAIT; volatile u8 bSelected = 0; volatile u16 max_reset = max_reset_normal / L_DIV; volatile u16 min_reset = min_reset_normal / L_DIV; volatile u16 presence = presence_normal / L_DIV; volatile u16 presence_delay = presence_delay_normal / L_DIV; volatile u16 null_slot = null_slot_normal / L_DIV; volatile u16 bit_range = bit_range_normal / L_DIV; volatile u16 tmp_word = 0; volatile u32 eeprom_counter; volatile u8 Tim2Smcr = 0; const u8 serial_def[] = {1, 2, 3, 4, 5, 6, 7, 15}; const u8 ver_nmb[] = {1, 0, 41}; //const u8 ver_nmb[] = {0xA5, 0xA5, 0xA5, 0xA5}; u8* serial_alt = (u8*)(EEPROM + 0); u8* serial = (u8*)serial_def; static u8 Match[] = {0, 0, 0, 0, 0, 0, 0, 0}; u8 serialTri[64]; volatile u8 enumCounter = 0; //Byte operations variables volatile u8 byteReceived = 0; volatile u8 byteReceivedMask = 1; volatile u8 byteToTransceive = 0x00; volatile u8 byteToTransceive2 = 0x00; volatile u8 bitCounter = 0; volatile u8 bitSerial = 0; volatile u8 byteCounter = 0; volatile u8 bOverdrive = NormalSpeed; volatile u8 uidCRC8; //static volatile u8 bIncrementCounter; static volatile u8 bIncrementEna; //volatile u32 SetupCounter; extern volatile u16 CRC16; u8 arrScratchPad[] = {0, 0, 0, 0, 0, 0, 0, 0}; u8 arrTestCRC[] = {0, 0}; u8 iSlotNumber = 0; u8* pSlotToTransceive = (u8*)EEPROM; u8 iPrevCommand = 0xFF; u16 WriteScratchpadCRC16Consts[SLOTS_AMOUNT]; u16 ReadMemoryCRC16Consts[SLOTS_AMOUNT]; void SetSpeedMode(void) { /* if(bOverdrive) { max_reset = max_reset_overdrive; min_reset = min_reset_overdrive; presence = presence_overdrive; presence_delay = presence_delay_overdrive; null_slot = null_slot_overdrive; bit_range = bit_range_overdrive; } */ //else //{ max_reset = max_reset_normal; min_reset = min_reset_normal; presence = presence_normal; presence_delay = presence_delay_normal; null_slot = null_slot_normal; bit_range = bit_range_normal; //} } static void CalcSlotCRC16(u16 numSlot) { u16 i = 0; CRC16 = 0; LIS3DH_crc16(ReadMemory); LIS3DH_crc16(numSlot); pSlotToTransceive = (u8*)(EEPROM + (numSlot << 3)); for(i = 0; i < sizeof arrScratchPad; i++) { LIS3DH_crc16((u16)(pSlotToTransceive[i])); } ReadMemoryCRC16Consts[numSlot] = CRC16; } void tim3_captured(u16 captime) { switch(mode) { case WAIT: //bSelected = 0; see asm.s break; case GETCMD: bitCounter = 0; byteReceivedMask = 1; TIM2_SetAutoreload(null_slot); if(!bSelected) { switch(byteReceived) { case Enumeration: enumCounter = 0; mode = ENUMERATION; byteToTransceive = serialTri[enumCounter++]; bitSerial = byteToTransceive & 1; TIM2->SMCR = bitSerial ? Tim2Smcr : 0; byteToTransceive >>= 1; break; case MatchDevice: byteCounter = 0; mode = MATCH_DEVICE; break; } } else { switch(byteReceived) { case InvalidRead: break; case InitAccel: LIS3DH_Init(); break; case GetVersion: mode = SEND_INFO; enumCounter = 3; pSlotToTransceive = (u8*)ver_nmb; LIS3DH_Stop(); byteCounter = 0; //byteToTransceive = ~ver_nmb[0]; byteToTransceive = ~pSlotToTransceive[0]; TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; break; case GetCounter: mode = SEND_INFO; enumCounter = 4; pSlotToTransceive = (u8*)&eeprom_counter; //pSlotToTransceive = (u8*)ver_nmb; LIS3DH_Stop(); byteCounter = 0; //byteToTransceive = ~ver_nmb[0]; byteToTransceive = ~pSlotToTransceive[0]; TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; break; case IncrementCounter: bIncrementEna = TRUE; //EEPROM_IncrementCounter(); break; case GetUid: mode = SEND_UID; pSlotToTransceive = (u8*)UID_ADDRESS; LIS3DH_Stop(); byteCounter = 0; byteToTransceive = ~pSlotToTransceive[byteCounter]; TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; break; case PingByte: mode = WRITEBYTE; byteToTransceive = ping_byte; TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; break; case OverdriveSkip: mode = WAIT; bOverdrive = OverdriveSpeed; SetSpeedMode(); break; case StartAccel: LIS3DH_Start(); //+ LIS3DH_Init(); //+ Restart in fact ABC break; case StopAccel: LIS3DH_Stop(); break; case GetAccelData: mode = SEND_ACCEL_DATA; byteToTransceive = ~LIS3DH_GetFirstFIFOData(&byteCounter); TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; break; case WriteScratchpad: mode = WRITE_SCRATCHPAD; LIS3DH_Stop(); byteCounter = 0; break; case CopyScratchpad: if(iPrevCommand != WriteScratchpad) { mode = WAIT; break; } mode = COPY_SCRATCHPAD; byteCounter = 0; break; case ReadMemory: mode = READ_MEMORY; LIS3DH_Stop(); byteCounter = 0; break; default: mode = WAIT; break; } } iPrevCommand = byteReceived; byteReceived = 0; break; case SEND_INFO: if(++bitCounter >= 8) { bitCounter = 0; if(++byteCounter >= enumCounter) { byteCounter = 0; mode = GETCMD; } else { //byteToTransceive = ver_nmb[byteCounter]; byteToTransceive = ~pSlotToTransceive[byteCounter]; //byteToTransceive = ~byteToTransceive; TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; } } byteReceived = 0; byteReceivedMask = 1; break; /* case SEND_COUNTER: if(++bitCounter >= 8) { bitCounter = 0; if(++byteCounter >= 4) { byteCounter = 0; mode = GETCMD; } else { //byteToTransceive = ver_nmb[byteCounter]; byteToTransceive = ~pSlotToTransceive[byteCounter]; //byteToTransceive = ~byteToTransceive; TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; } } byteReceived = 0; byteReceivedMask = 1; break; */ case READ_MEMORY: if(byteReceived >= SLOTS_AMOUNT) { mode = WAIT; break; } iSlotNumber = byteReceived; pSlotToTransceive = (u8*)(EEPROM + ((uint16_t)iSlotNumber << 3)); bitCounter = 0; byteCounter = 0; mode = SEND_SLOT; byteToTransceive = pSlotToTransceive[byteCounter]; byteToTransceive = ~(byteToTransceive); TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; byteReceivedMask = 1; byteReceived = 0; break; case SEND_UID: if(++bitCounter >= 8) { bitCounter = 0; if(++byteCounter > UID_LENGTH) { byteCounter = 0; mode = GETCMD; } else if(byteCounter == UID_LENGTH) { byteToTransceive = uidCRC8; byteToTransceive = ~byteToTransceive; TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; } else { byteToTransceive = pSlotToTransceive[byteCounter]; byteToTransceive = ~byteToTransceive; TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; } } byteReceived = 0; byteReceivedMask = 1; break; case SEND_SLOT: if(++bitCounter >= 8) { bitCounter = 0; if(++byteCounter >= 8) { byteCounter = 0; bitCounter = 0; mode = SEND_CRC16; CRC16 = ReadMemoryCRC16Consts[iSlotNumber]; byteToTransceive = ~(CRC16 & 0xFF); TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; } else { byteToTransceive = pSlotToTransceive[byteCounter]; byteToTransceive = ~byteToTransceive; TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; } } byteReceived = 0; byteReceivedMask = 1; break; case COPY_SCRATCHPAD: arrTestCRC[byteCounter++] = byteReceived; if(byteCounter >= 2) { tmp_word = arrTestCRC[1] << 8 | arrTestCRC[0]; if(tmp_word != CRC16) { mode = WAIT; break; } if(EEPROM_CopyScratchPad(iSlotNumber, arrScratchPad) == 0) { mode = WAIT; break; } CalcSlotCRC16(iSlotNumber); CRC16 = tmp_word; byteCounter = 0; bitCounter = 0; mode = SEND_CRC16; byteToTransceive = ~(CRC16 & 0xFF); TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; break; } byteReceivedMask = 1; byteReceived = 0; break; case WRITE_SCRATCHPAD: if(byteCounter == 0) { iSlotNumber = byteReceived; CRC16 = WriteScratchpadCRC16Consts[byteReceived]; } else { LIS3DH_crc16((u16)byteReceived); arrScratchPad[byteCounter - 1] = byteReceived; } if(byteCounter >= sizeof arrScratchPad) { byteCounter = 0; bitCounter = 0; mode = SEND_CRC16; byteToTransceive = ~(CRC16 & 0xFF); TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; break; } byteReceived = 0; byteReceivedMask = 1; byteCounter++; break; case SEND_CRC16: if(++bitCounter >= 8) { bitCounter = 0; if(++byteCounter >= 2) { mode = GETCMD; } else { byteToTransceive = ~(CRC16 >> 8); TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; } } byteReceived = 0; byteReceivedMask = 1; break; case SEND_ACCEL_DATA: if(++bitCounter >= 8) { bitCounter = 0; if(--byteCounter == 0) { mode = GETCMD; if(LIS3DH_GetFIFODataEnd() == FIFO_OVERFLOW) { LIS3DH_Stop(); mode = WAIT; } /* if(bIncrementCounter) { bIncrementCounter = FALSE; bIncrementEna = TRUE; } */ } else { byteToTransceive = ~LIS3DH_GetNextFIFOData(); TIM2->SMCR = byteToTransceive & 1 ? Tim2Smcr : 0; byteToTransceive >>= 1; } } byteReceived = 0; byteReceivedMask = 1; break; case MATCH_DEVICE: bitCounter = 0; Match[byteCounter] = byteReceived; byteReceived = 0; byteReceivedMask = 1; if(++byteCounter >= 8) { bitCounter = 0; byteCounter = 0; for(byteCounter = 0; byteCounter < 8; byteCounter++) { if(serial[byteCounter] != Match[byteCounter]) { mode = WAIT; break; } } if(mode == WAIT) { break; } mode = GETCMD; bSelected = 1; } break; case WRITEBYTE: if(++bitCounter >= 8) { bitCounter = 0; mode = GETCMD; } break; case ENUMERATION: if(++bitCounter >= 3) { bitCounter = 0; if(captime < bit_range) { if(bitSerial) { mode = WAIT; TIM2->SMCR = 0; break; } } else { if(!bitSerial) { mode = WAIT; TIM2->SMCR = 0; break; } } if(enumCounter < 64) { byteToTransceive = serialTri[enumCounter++]; bitSerial = byteToTransceive & 1; TIM2->SMCR = bitSerial ? Tim2Smcr : 0; byteToTransceive >>= 1; } else { mode = GETCMD; TIM2->SMCR = 0; bSelected = 1; } } break; }//switch } static void InitClocks(void) { CLK_DeInit(); CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv8); CLK_PeripheralClockConfig(CLK_Peripheral_TIM2 | CLK_Peripheral_TIM3 | CLK_Peripheral_TIM4 | CLK_Peripheral_SPI, ENABLE); } static void InitGPIO(void) { GPIO_DeInit(GPIOC); GPIO_Init(GPIOC, GPIO_Pin_3, GPIO_Mode_Out_PP_Low_Fast); GPIO_SetBits(GPIOC, GPIO_Pin_3); GPIO_DeInit(GPIOB); GPIO_Init(GPIOB, GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6, GPIO_Mode_Out_PP_Low_Fast); GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_In_PU_No_IT); } static void InitSerialNumber(void) { int i= 0, j = 0, k = 0; u8 byteSerial; while(i < 64) { byteSerial = serial[j++]; for(k = 0; k < 8; k++) { if(byteSerial & (1 << k)) { serialTri[i++] = 0x02; } else { serialTri[i++] = 0x01; } } } } static void InitTimer2(void) { TIM2_DeInit(); TIM2_TimeBaseInit(TIM2_Prescaler_1, TIM2_CounterMode_Up, null_slot); TIM2_ICInit(TIM2_Channel_1, TIM2_ICPolarity_Falling, TIM2_ICSelection_DirectTI, TIM2_ICPSC_Div1, 0); TIM2_OC2Init(TIM2_OCMode_PWM1, TIM2_OutputState_Enable,// TIM2_OUTPUTNSTATE_DISABLE, presence_delay, TIM2_OCPolarity_Low,// TIM2_OCNPOLARITY_HIGH, TIM2_OCIdleState_Reset//, TIM2_OCIDLESTATE_RESET ); TIM2->BKR = 0x80; TIM2_SelectInputTrigger(TIM2_TRGSelection_TI1FP1); TIM2_SelectSlaveMode(TIM2_SlaveMode_Trigger); Tim2Smcr = TIM2->SMCR; TIM2->SMCR = 0; TIM2_SelectOnePulseMode(TIM2_OPMode_Single); TIM2_OC2FastCmd(ENABLE); } static void InitTimer3(void) { TIM3_DeInit(); TIM3_TimeBaseInit(TIM3_Prescaler_1,TIM3_CounterMode_Up, 0xFFFF); TIM3_ICInit(TIM3_Channel_1, TIM3_ICPolarity_Falling, TIM3_ICSelection_DirectTI, TIM3_ICPSC_Div1, 0); TIM3_ICInit(TIM3_Channel_2, TIM3_ICPolarity_Rising, TIM3_ICSelection_IndirectTI, TIM3_ICPSC_Div1, 0); TIM3_SelectInputTrigger(TIM3_TRGSelection_TI1FP1); TIM3_SelectSlaveMode(TIM3_SlaveMode_Reset); TIM3_ITConfig(TIM3_IT_CC2, ENABLE); ITC_SetSoftwarePriority(TIM3_CAP_IRQn, ITC_PriorityLevel_2); TIM3_Cmd(ENABLE); } static void InitTimer4(void) { TIM4_DeInit(); TIM4_TimeBaseInit(TIM4_Prescaler_32768, 8); TIM4_ITConfig(TIM4_IT_Update, ENABLE); ITC_SetSoftwarePriority(TIM4_UPD_OVF_IRQn, ITC_PriorityLevel_1); TIM4_Cmd(ENABLE); } static void InitSpi(void) { SPI_DeInit(); SPI_Init(SPI_FirstBit_MSB, SPI_BaudRatePrescaler_2, SPI_Mode_Master, SPI_CPOL_High, SPI_CPHA_2Edge, SPI_Direction_2Lines_FullDuplex, SPI_NSS_Soft); SPI_Cmd(ENABLE); } static void InitEXTI(void) { EXTI_DeInit(); EXTI_SetPinSensitivity(EXTI_Pin_4, EXTI_Trigger_Falling_Low); ITC_SetSoftwarePriority(EXTI4_IRQn, ITC_PriorityLevel_1); } static void InitCRC16Consts(void) { u16 i = 0; for(i = 0; i < SLOTS_AMOUNT; i++) { CRC16 = 0; LIS3DH_crc16(WriteScratchpad); LIS3DH_crc16(i); WriteScratchpadCRC16Consts[i] = CRC16; CalcSlotCRC16(i); } } u8 tmp_byte; static void SetSerialNumber(void) { if(EEPROM_CalcCrcFunc(serial_alt, 8) == 0) { serial = serial_alt; } } static void SetUidCrc(void) { uidCRC8 = EEPROM_CalcCrcFunc((u8*)UID_ADDRESS, UID_LENGTH); } extern volatile u8 bDataReady; void main(void) { //bIncrementCounter = FALSE; bIncrementEna = FALSE; mode = WAIT; disableInterrupts(); InitClocks(); InitCRC16Consts(); SetSerialNumber(); SetUidCrc(); EEPROM_InitCounter(); InitGPIO(); InitTimer2(); InitTimer3(); InitTimer4(); InitSpi(); InitEXTI(); LIS3DH_Init(); //tmp_word = LIS3DH_GetId(); InitSerialNumber(); enableInterrupts(); CLK_MasterPrescalerConfig(CLK_Prescaler); #ifdef USE_IWDG //InitWatchdog(); #endif while(1) { wfi(); if(bIncrementEna) { bIncrementEna = FALSE; EEPROM_IncrementCounter(); } ResetWatchdog(); } }