diff --git a/MotorDriver/Drivers/bus/bus_driver.c b/MotorDriver/Drivers/bus/bus_driver.c index 428e96d..d577a51 100644 --- a/MotorDriver/Drivers/bus/bus_driver.c +++ b/MotorDriver/Drivers/bus/bus_driver.c @@ -6,7 +6,12 @@ #include #include "bus_driver.h" - +//! Free bus flag +static volatile bool _BusFree = true; +//! Message is pending to send +static volatile bool _TxPending = false; +//! Tranmission ongoing +static volatile bool _TxOngoing = false; //! Receive buffer static uint8_t _RxBuff[BUS_BUFF_NUM][BUS_BUFF_LEN]; //! Rx message index @@ -15,8 +20,12 @@ static uint8_t _RxMsg = 0; static uint8_t _RxData = 0; //! Rx overflowed static bool _RxOverflow = false; - -static uint8_t _TempDR; +//! Transmit buffer +static uint8_t _TxBuff[BUS_BUFF_LEN]; +//! Tx data index +static uint8_t _TxData = 0; +//! Tx data to send +static uint8_t _TxLen = 0; uint16_t _sr; @@ -43,6 +52,15 @@ void BUS_Init(void) BUS_GPIO->CRH &= ~(GPIO_CRH_CNF10 | GPIO_CRH_CNF11 | GPIO_CRH_MODE11); BUS_GPIO->CRH |= GPIO_CRH_CNF11_0 | GPIO_CRH_MODE10_1; + #ifdef BUS_TIM_USED + //1÷(72000000÷65535÷3) ~~ 2.7ms + BUS_TIM->PSC = 3; + BUS_TIM->DIER |= TIM_DIER_UIE; + NVIC_EnableIRQ(TIM2_IRQn); + // enable BUS_TIM module + BUS_TIM->CR1 |= OPM; + #endif + //! Calculated on asap: //! 36000000 / (16 * 38400) = 585.9375 //! DIV_Mantissa = 585 @@ -54,12 +72,30 @@ void BUS_Init(void) NVIC_EnableIRQ(USART3_IRQn); } +#ifdef BUS_TIM_USED +void TIM2_IRQHandler(void) + { + //! Send message if was pending + if(_TxPending) + { + _TxOngoing = true; + _TxPending = false; + // Set interupt on clearing TX register. + BUS_UART->CR1 |= USART_CR1_TXEIE; + // start uart transmission + BUS_UART->DR = _TxBuff[_TxData++]; + } + else _BusFree = true; + } +#endif void USART3_IRQHandler(void) { + uint8_t _TempDR; _sr = BUS_UART->SR; if(_sr & USART_SR_RXNE) { + _BusFree = false; if(_RxData < BUS_BUFF_LEN) _RxBuff[_RxMsg][_RxData++] = BUS_UART->DR; else _RxOverflow = true; } @@ -67,7 +103,7 @@ void USART3_IRQHandler(void) { //! Read DR to clear flag _TempDR = BUS_UART->DR; - + uint8_t temp_RxMsg = _RxMsg; uint8_t temp_RxData = _RxData; bool temp_RxOverflow = _RxOverflow; @@ -78,10 +114,74 @@ void USART3_IRQHandler(void) //! Call receive function if receive buffer is not overflowed if(!temp_RxOverflow) BUS_Received(_RxBuff[temp_RxMsg], temp_RxData); + + #ifdef BUS_TIM_USED + BUS_TIM->CNT = 0; // just in case, it should be 0 already. + // timer enable + BUS_TIM->CR1 |= TIM_CR1_CEN; + #else + //! Send message if was pending + if(_TxPending) + { + _TxOngoing = true; + _TxPending = false; + // Set interupt on clearing TX register. + BUS_UART->CR1 |= USART_CR1_TXEIE; + // start uart transmission + BUS_UART->DR = _TxBuff[_TxData++]; + } + else _BusFree = true; + #endif + } + if(_sr & USART_SR_TXE && _TxOngoing) + { + if(_TxData < _TxLen) BUS_UART->DR = _TxBuff[_TxData++]; + else + { + // clear interupt on clearing TX register. + BUS_UART->CR1 &= ~USART_CR1_TXEIE; + _BusFree = true; + _TxOngoing = false; + } } if(_sr & (USART_SR_ORE || USART_SR_FE || USART_SR_NE )) { - _sr = BUS_UART->DR; + _TempDR = BUS_UART->DR; + } +} + +void BUS_Send(uint8_t *buff, uint8_t len) +{ + //! Dump message if transmission is already ongoing or buffered + if(_TxOngoing || _TxPending) return; + + if( len > BUS_BUFF_LEN) len = BUS_BUFF_LEN; + + //! Copy passed message to internal buffer + for(uint8_t i=0; iCR1 |= USART_CR1_TXEIE; + BUS_UART->DR = _TxBuff[_TxData++]; } + //! Pend message to be send after received frame + else _TxPending = true; } +void BUS_SendBlocking(uint8_t *buff, uint8_t len) +{ + for(uint8_t i=0; iSR & USART_SR_TXE)); + BUS_UART->DR = buff[i]; + } +} diff --git a/MotorDriver/Drivers/system/system_driver.c b/MotorDriver/Drivers/system/system_driver.c index 97b78e2..15bddc3 100644 --- a/MotorDriver/Drivers/system/system_driver.c +++ b/MotorDriver/Drivers/system/system_driver.c @@ -5,6 +5,7 @@ #include "system_driver.h" #include "stm32f10x.h" +#include "hardware.h" uint32_t _Tick; @@ -43,6 +44,9 @@ void SYS_Init(void) RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_ADC1EN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_AFIOEN; RCC->APB1ENR |= RCC_APB1ENR_TIM3EN | RCC_APB1ENR_TIM4EN | RCC_APB1ENR_USART3EN; + #ifdef BUS_TIM_USED + RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; + #endif RCC->AHBENR |= RCC_AHBENR_DMA1EN; diff --git a/MotorDriver/Inc/hardware.h b/MotorDriver/Inc/hardware.h index da26f4d..73eb777 100644 --- a/MotorDriver/Inc/hardware.h +++ b/MotorDriver/Inc/hardware.h @@ -40,6 +40,8 @@ #define BUS_TX_PIN GPIO_PIN_10 #define BUS_RX_PIN GPIO_PIN_11 #define BUS_UART USART3 +#define BUS_TIM TIM2 +//#define BUS_TIM_USED // define to use TIMER //! ########################### ENCODER ########################### #define ENC_GPIO GPIOB diff --git a/MotorDriver/Libraries/message/msg_lib.c b/MotorDriver/Libraries/message/msg_lib.c index b2709cb..81c8651 100644 --- a/MotorDriver/Libraries/message/msg_lib.c +++ b/MotorDriver/Libraries/message/msg_lib.c @@ -47,15 +47,35 @@ uint8_t MSG_CalculateCrc(uint8_t *data, uint8_t len) bool MSG_ValidateCrc(uint8_t *data, uint8_t len) { - if(MSG_CalculateCrc(data, len)) return false; //tu chyba len-1 + if(MSG_CalculateCrc(data, len)) return false; else return true; } - void BUS_Received(uint8_t *buff, uint8_t len) { - if(buff[0]==ADDRESS && MSG_ValidateCrc(&buff[0],buff[2]+4)) - MSG_Received(&buff[3],len-4); + if(buff[0]==ADDRESS && MSG_ValidateCrc(&buff[0],buff[2]+4)) + MSG_Received(&buff[3],len-4); +} +uint8_t MSG_Pack(MSG_Command cmd, uint8_t *data, uint8_t len, uint8_t *buff) +{ + MSG_Message *msg = (MSG_Message *) buff; + //! Set address and command + msg->Address = ADDRESS; + msg->Command = cmd; + msg->Length = len; + //! Copy passed data to buffer + for(uint8_t i=0; iPayload[i] =data[i]; + //! Append CRC + msg->Payload[len] = MSG_CalculateCrc(buff, len + 3); + //! Return size of packed message + return len + 4; } + +uint8_t MSG_PackDriverState(uint8_t volt, uint8_t amp, uint8_t rpm, uint8_t *buff) +{ + uint8_t data[3] = {volt, amp, rpm}; + return MSG_Pack(MSG_DRV_STATE, data, 3, buff); +} \ No newline at end of file diff --git a/MotorDriver/Libraries/message/msg_lib.h b/MotorDriver/Libraries/message/msg_lib.h index f728c49..06cb81c 100644 --- a/MotorDriver/Libraries/message/msg_lib.h +++ b/MotorDriver/Libraries/message/msg_lib.h @@ -18,6 +18,7 @@ typedef enum { MSG_NOT_VALID, MSG_BTN_STATE, + MSG_DRV_STATE } MSG_Command; @@ -25,7 +26,7 @@ typedef enum typedef struct { uint8_t Address; - MSG_Command Command; + uint8_t Command; uint8_t Length; uint8_t Payload[]; } MSG_Message; @@ -36,5 +37,8 @@ uint8_t MSG_CalculateCrc(uint8_t *data, uint8_t len); bool MSG_ValidateCrc(uint8_t *data, uint8_t len); void __attribute__((weak)) MSG_Received(uint8_t *buff, uint8_t len); +uint8_t MSG_Pack(MSG_Command cmd, uint8_t *data, uint8_t len, uint8_t *buff); +uint8_t MSG_PackDriverState(uint8_t volt, uint8_t amp, uint8_t rpm, uint8_t *buff); + #endif /* MSG_LIB_H_ */ diff --git a/MotorDriver/Src/main.c b/MotorDriver/Src/main.c index 9892caa..4d1a109 100644 --- a/MotorDriver/Src/main.c +++ b/MotorDriver/Src/main.c @@ -24,6 +24,8 @@ bool _MotorState = false; uint8_t _ControllerState=0; uint8_t _MessageTimer = 0; +uint8_t messageBuffer[7]; + const uint16_t _CurrentTable[120] = {2045, 2105, 2164, 2224, 2283, 2343, 2402, 2462, 2522, 2581, 2590, 2586, 2582, 2579, 2575, 2571, 2567, 2564, 2560, 2556, 2553, 2549, 2545, 2541, 2538, 2518, 2497, 2477, 2457, 2437, 2417, 2397, 2377, 2357, 2337, 2317, 2296, 2276, 2256, 2236, 2216, 2196, 2176, 2156, 2136, 2116, 2095, 2075, 2055, 2035, 2009, 2008, 2007, 2007, 2006, 2006, 2005, 2005, 2004, 2004, 2003, 2003, 2002, 2002, 2001, 2001, 2000, 2000, 1999, 1999, 1998, 1998, 1997, 1997, 1996, 1995, 1995, 1994, 1994, 1993, 1993, 1992, 1992, 1991, 1991, 1990, 1990, 1989, 1989, 1988, 1988, 1987, 1987, 1986, 1986, 1985, 1985, 1984, 1983, 1983, 1982, 1982, 1981, 1981, 1980, 1980, 1979, 1979, 1978, 1978, 1977, 1977, 1976, 1976, 1975, 1975, 1974, 1974, 1973, 1973}; @@ -100,6 +102,7 @@ int main(void) //! Systick handler called in interrupt void SYS_Tick(void) { + //! Read rpm value from encoder _Rpm = ENC_ReadAndReset(); //! Calculate rpm to table index value @@ -110,20 +113,18 @@ void SYS_Tick(void) { MTR_SetLimit(_CurrentTable1[_TableIndex]); } - - else MTR_SetLimit(_CurrentTable[_TableIndex]); //! TODO: Handle events if(_MessageTimer > 10) { - _ControllerState=0; - - - } else _MessageTimer++; + + // send telemetry packet every 10ms. + uint8_t len = MSG_PackDriverState(4 /*volt*/, 2 /*amp*/, 0 /*rpm*/, messageBuffer); + BUS_Send(messageBuffer, len); }