diff --git a/ATSAMD21/luos_hal.c b/ATSAMD21/luos_hal.c index 4dab61d..51a59fb 100644 --- a/ATSAMD21/luos_hal.c +++ b/ATSAMD21/luos_hal.c @@ -1,6 +1,6 @@ /****************************************************************************** * @file luosHAL - * @brief Luos Hardware Abstration Layer. Describe Low layer fonction + * @brief Luos Hardware Abstration Layer. Describe Low layer fonction * @MCU Family ATSAMD21 * @author Luos * @version 0.0.0 @@ -18,12 +18,12 @@ /******************************************************************************* * Definitions ******************************************************************************/ +#define DEFAULT_TIMEOUT 20 /******************************************************************************* * Variables ******************************************************************************/ volatile uint32_t tick; -uint32_t Timer_Reload = ((MCUFREQ /DEFAULTBAUDRATE)*20); //20us//2*10bits typedef struct { @@ -33,6 +33,15 @@ typedef struct } Port_t; Port_t PTP[NBR_PORT]; + +volatile uint16_t timoutclockcnt = 0; +volatile uint16_t data_size_to_transmit = 0; +volatile uint8_t *tx_data = 0; + +#ifndef USE_TX_IT +static dmac_descriptor_registers_t write_back_section __ALIGNED(8); +static dmac_descriptor_registers_t descriptor_section __ALIGNED(8); +#endif /******************************************************************************* * Function ******************************************************************************/ @@ -40,12 +49,8 @@ static void LuosHAL_SystickInit(void); static void LuosHAL_FlashInit(void); static void LuosHAL_CRCInit(void); static void LuosHAL_TimeoutInit(void); -static void LuosHAL_ResetTimeout(void); -static inline void LuosHAL_ComTimeout(void); static void LuosHAL_GPIOInit(void); static void LuosHAL_FlashEraseLuosMemoryInfo(void); -static inline void LuosHAL_ComReceive(void); -static inline void LuosHAL_GPIOProcess(uint16_t GPIO); static void LuosHAL_RegisterPTP(void); /////////////////////////Luos Library Needed function/////////////////////////// @@ -59,7 +64,7 @@ void LuosHAL_Init(void) { //Systick Initialization LuosHAL_SystickInit(); - + //IO Initialization LuosHAL_GPIOInit(); @@ -96,9 +101,9 @@ void LuosHAL_SetIrqState(uint8_t Enable) static void LuosHAL_SystickInit(void) { SysTick->CTRL = 0; - SysTick->VAL = 0; - SysTick->LOAD = 0xbb80 - 1; - SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_CLKSOURCE_Msk; + SysTick->VAL = 0; + SysTick->LOAD = 0xbb80 - 1; + SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_CLKSOURCE_Msk; SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; } /****************************************************************************** @@ -132,20 +137,20 @@ void LuosHAL_ComInit(uint32_t Baudrate) /* Disable the USART before configurations */ LUOS_COM->USART_INT.SERCOM_CTRLA &= ~SERCOM_USART_INT_CTRLA_ENABLE_Msk; - + /* Configure Baud Rate */ baud = 65536 - ((uint64_t)65536 * 16 * Baudrate) / MCUFREQ; LUOS_COM->USART_INT.SERCOM_BAUD = SERCOM_USART_INT_BAUD_BAUD(baud); //Configures USART Clock Mode/ TXPO and RXPO/ Data Order/ Standby Mode/ Sampling rate/ IBON - LUOS_COM->USART_INT.SERCOM_CTRLA = SERCOM_USART_INT_CTRLA_MODE_USART_INT_CLK | SERCOM_USART_INT_CTRLA_RXPO(COM_RX_POS) - | SERCOM_USART_INT_CTRLA_TXPO(COM_TX_POS) | SERCOM_USART_INT_CTRLA_DORD_Msk - | SERCOM_USART_INT_CTRLA_IBON_Msk | SERCOM_USART_INT_CTRLA_FORM(0x0) + LUOS_COM->USART_INT.SERCOM_CTRLA = SERCOM_USART_INT_CTRLA_MODE_USART_INT_CLK | SERCOM_USART_INT_CTRLA_RXPO(COM_RX_POS) + | SERCOM_USART_INT_CTRLA_TXPO(COM_TX_POS) | SERCOM_USART_INT_CTRLA_DORD_Msk + | SERCOM_USART_INT_CTRLA_IBON_Msk | SERCOM_USART_INT_CTRLA_FORM(0x0) | SERCOM_USART_INT_CTRLA_SAMPR(0) ; - + //Configures RXEN/ TXEN/ CHSIZE/ Parity/ Stop bits - LUOS_COM->USART_INT.SERCOM_CTRLB = SERCOM_USART_INT_CTRLB_CHSIZE_8_BIT | SERCOM_USART_INT_CTRLB_SBMODE_1_BIT - | SERCOM_USART_INT_CTRLB_RXEN_Msk | SERCOM_USART_INT_CTRLB_TXEN_Msk + LUOS_COM->USART_INT.SERCOM_CTRLB = SERCOM_USART_INT_CTRLB_CHSIZE_8_BIT | SERCOM_USART_INT_CTRLB_SBMODE_1_BIT + | SERCOM_USART_INT_CTRLB_RXEN_Msk | SERCOM_USART_INT_CTRLB_TXEN_Msk | SERCOM_USART_INT_CTRLB_SFDE_Msk ; /* Enable the UART after the configurations */ @@ -156,19 +161,28 @@ void LuosHAL_ComInit(uint32_t Baudrate) /* Clean IT */ LUOS_COM->USART_INT.SERCOM_INTENSET = SERCOM_USART_INT_INTENSET_RESETVALUE; - - /* Enable error interrupt */ - LUOS_COM->USART_INT.SERCOM_INTENSET = SERCOM_USART_INT_INTENSET_ERROR_Msk; /* Enable Receive Complete interrupt */ LUOS_COM->USART_INT.SERCOM_INTENSET = SERCOM_USART_INT_INTENSET_RXC_Msk; - + NVIC_SetPriority(LUOS_COM_IRQ, 3); NVIC_EnableIRQ(LUOS_COM_IRQ); //Timeout Initialization - Timer_Reload = ((MCUFREQ /Baudrate)*20); //20us//2*10bits + timoutclockcnt = MCUFREQ /Baudrate; LuosHAL_TimeoutInit(); + +#ifndef USE_TX_IT + LUOS_DMA_CLOCK_ENABLE(); + + LUOS_DMA->DMAC_BASEADDR = (uint32_t)&descriptor_section; + LUOS_DMA->DMAC_WRBADDR = (uint32_t)&write_back_section; + LUOS_DMA->DMAC_PRICTRL0 = DMAC_PRICTRL0_LVLPRI0(1UL) | DMAC_PRICTRL0_RRLVLEN0_Msk | DMAC_PRICTRL0_LVLPRI1(1UL) | DMAC_PRICTRL0_RRLVLEN1_Msk | DMAC_PRICTRL0_LVLPRI2(1UL) | DMAC_PRICTRL0_RRLVLEN2_Msk | DMAC_PRICTRL0_LVLPRI3(1UL) | DMAC_PRICTRL0_RRLVLEN3_Msk; + LUOS_DMA->DMAC_CHID = LUOS_DMA_CHANNEL;//DMA Channel + LUOS_DMA->DMAC_CHCTRLB = DMAC_CHCTRLB_TRIGACT(2) | DMAC_CHCTRLB_TRIGSRC(LUOS_DMA_TRIGGER) | DMAC_CHCTRLB_LVL(0) ; + descriptor_section.DMAC_BTCTRL = DMAC_BTCTRL_BLOCKACT_INT | DMAC_BTCTRL_BEATSIZE_BYTE | DMAC_BTCTRL_VALID_Msk | DMAC_BTCTRL_SRCINC_Msk ; + LUOS_DMA->DMAC_CTRL = DMAC_CTRL_DMAENABLE_Msk | DMAC_CTRL_LVLEN0_Msk | DMAC_CTRL_LVLEN1_Msk | DMAC_CTRL_LVLEN2_Msk | DMAC_CTRL_LVLEN3_Msk; +#endif } /****************************************************************************** * @brief Tx enable/disable relative to com @@ -179,20 +193,30 @@ void LuosHAL_SetTxState(uint8_t Enable) { if (Enable == true) { - PORT_REGS->GROUP[COM_TX_PORT].PORT_PINCFG[COM_TX_PIN] &= ~PORT_PINCFG_PULLEN; //TX push pull + PORT_REGS->GROUP[COM_TX_PORT].PORT_PINCFG[COM_TX_PIN] &= ~PORT_PINCFG_PULLEN_Msk; //TX push pull if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - PORT_REGS->GROUP[TX_EN_PORT].PORT_OUTSET = (1 << TX_EN_PIN); //enable Tx - } + { + PORT_REGS->GROUP[TX_EN_PORT].PORT_OUTSET = (1 << TX_EN_PIN); //enable Tx + } } else { - PORT_REGS->GROUP[COM_TX_PORT].PORT_PINCFG[COM_TX_PIN] |= PORT_PINCFG_PULLEN;//Tx Open drain + PORT_REGS->GROUP[COM_TX_PORT].PORT_PINCFG[COM_TX_PIN] |= PORT_PINCFG_PULLEN_Msk;//Tx Open drain if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - PORT_REGS->GROUP[TX_EN_PORT].PORT_OUTCLR = (1 << TX_EN_PIN); //disable Tx + { + PORT_REGS->GROUP[TX_EN_PORT].PORT_OUTCLR = (1 << TX_EN_PIN); //disable Tx } - LUOS_COM->USART_INT.SERCOM_INTFLAG |= SERCOM_USART_EXT_INTFLAG_RXS(0); +#ifdef USE_TX_IT + // Stop current transmit operation + data_size_to_transmit = 0; + // Disable Transmission empty buffer interrupt + LUOS_COM->USART_INT.SERCOM_INTENCLR = SERCOM_USART_INT_INTENCLR_DRE_Msk;//disable IT +#else + LUOS_DMA->DMAC_CHCTRLA &= ~DMAC_CHCTRLA_ENABLE_Msk; +#endif + // Disable Transmission complete interrupt + LUOS_COM->USART_INT.SERCOM_INTENCLR = SERCOM_USART_INT_INTENCLR_TXC_Msk;//disable IT + LUOS_COM->USART_INT.SERCOM_INTFLAG = SERCOM_USART_INT_INTFLAG_RXS_Msk; } } @@ -207,18 +231,12 @@ void LuosHAL_SetRxState(uint8_t Enable) { LUOS_COM->USART_INT.SERCOM_DATA;//clear data buffer LUOS_COM->USART_INT.SERCOM_CTRLB |= SERCOM_USART_INT_CTRLB_RXEN_Msk; - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - PORT_REGS->GROUP[RX_EN_PORT].PORT_OUTCLR = (1 << RX_EN_PIN); //enable rx - } + LUOS_COM->USART_INT.SERCOM_INTENSET = SERCOM_USART_INT_INTENSET_RXC_Msk; } else { - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - PORT_REGS->GROUP[RX_EN_PORT].PORT_OUTSET = (1 << RX_EN_PIN); //disable rx - } LUOS_COM->USART_INT.SERCOM_CTRLB &= ~SERCOM_USART_INT_CTRLB_RXEN_Msk; + LUOS_COM->USART_INT.SERCOM_INTENCLR = SERCOM_USART_INT_INTENCLR_RXC_Msk; } } /****************************************************************************** @@ -226,76 +244,115 @@ void LuosHAL_SetRxState(uint8_t Enable) * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComReceive(void) +void LUOS_COM_IRQHANDLER() { - uint8_t data = 0; + // Reset timeout to it's default value + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); - LuosHAL_ResetTimeout(); - - // check if we receive a data - if((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_RXC_Msk) == SERCOM_USART_INT_INTFLAG_RXC_Msk) + // reception management + if(((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_RXC_Msk) == SERCOM_USART_INT_INTFLAG_RXC_Msk)&& + ((LUOS_COM->USART_INT.SERCOM_INTENSET & SERCOM_USART_INT_INTENSET_RXC_Msk) == SERCOM_USART_INT_INTENSET_RXC_Msk)) { //clean start bit detection - data = LUOS_COM->USART_INT.SERCOM_DATA; + uint8_t data = LUOS_COM->USART_INT.SERCOM_DATA; ctx.rx.callback(&data); + if (data_size_to_transmit == 0) + { + LUOS_COM->USART_INT.SERCOM_STATUS = SERCOM_USART_INT_STATUS_PERR_Msk | SERCOM_USART_INT_STATUS_FERR_Msk | SERCOM_USART_INT_STATUS_BUFOVF_Msk; + LUOS_COM->USART_INT.SERCOM_INTFLAG = SERCOM_USART_INT_INTFLAG_RXS_Msk; + return; + } + } + else if((LUOS_COM->USART_INT.SERCOM_STATUS & SERCOM_USART_INT_STATUS_FERR_Msk) == SERCOM_USART_INT_STATUS_FERR_Msk) + { + ctx.rx.status.rx_framing_error = true; } - // check error on ligne - else if((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_ERROR_Msk) == SERCOM_USART_INT_INTFLAG_ERROR_Msk) + + // Transmission management + if(((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_TXC_Msk) == SERCOM_USART_INT_INTFLAG_TXC_Msk)&& + ((LUOS_COM->USART_INT.SERCOM_INTENSET & SERCOM_USART_INT_INTENSET_TXC_Msk) == SERCOM_USART_INT_INTENSET_TXC_Msk)) + { + // Transmission complete + // Switch to reception mode + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); + // Disable transmission complete IRQ + LUOS_COM->USART_INT.SERCOM_INTFLAG = SERCOM_USART_INT_INTFLAG_TXC_Msk;//clear flag + LUOS_COM->USART_INT.SERCOM_INTENCLR = SERCOM_USART_INT_INTENCLR_TXC_Msk;//disable IT + } +#ifdef USE_TX_IT + else if(((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_DRE_Msk) == SERCOM_USART_INT_INTFLAG_DRE_Msk)&& + ((LUOS_COM->USART_INT.SERCOM_INTENSET & SERCOM_USART_INT_INTENSET_DRE_Msk) == SERCOM_USART_INT_INTENSET_DRE_Msk)) { - if((LUOS_COM->USART_INT.SERCOM_STATUS & SERCOM_USART_INT_STATUS_FERR_Msk) == SERCOM_USART_INT_STATUS_FERR_Msk) - { - ctx.rx.status.rx_framing_error = true; - } - LUOS_COM->USART_INT.SERCOM_STATUS = SERCOM_USART_INT_STATUS_PERR_Msk | SERCOM_USART_INT_STATUS_FERR_Msk | SERCOM_USART_INT_STATUS_BUFOVF_Msk; - LUOS_COM->USART_INT.SERCOM_INTFLAG |= SERCOM_USART_INT_INTENCLR_ERROR(0); - - while((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_RXC_Msk) == SERCOM_USART_INT_INTFLAG_RXC_Msk) + // Transmit buffer empty (this is a software DMA) + data_size_to_transmit--; + LUOS_COM->USART_INT.SERCOM_DATA = *(tx_data++); + if (data_size_to_transmit == 0) { - data = LUOS_COM->USART_INT.SERCOM_DATA; + // Transmission complete, stop loading data and watch for the end of transmission + // Disable Transmission empty buffer interrupt + LUOS_COM->USART_INT.SERCOM_INTFLAG = SERCOM_USART_INT_INTFLAG_DRE_Msk;//clear flag + LUOS_COM->USART_INT.SERCOM_INTENCLR = SERCOM_USART_INT_INTENCLR_DRE_Msk;//disable IT + // Enable Transmission complete interrupt + LUOS_COM->USART_INT.SERCOM_INTENSET = SERCOM_USART_INT_INTENSET_TXC_Msk;//disable IT } } - LUOS_COM->USART_INT.SERCOM_INTFLAG |= SERCOM_USART_EXT_INTFLAG_RXS(0); +#endif + LUOS_COM->USART_INT.SERCOM_STATUS = SERCOM_USART_INT_STATUS_PERR_Msk | SERCOM_USART_INT_STATUS_FERR_Msk | SERCOM_USART_INT_STATUS_BUFOVF_Msk; + LUOS_COM->USART_INT.SERCOM_INTFLAG = SERCOM_USART_INT_INTFLAG_RXS_Msk; + } /****************************************************************************** * @brief Process data transmit * @param None * @return None ******************************************************************************/ -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size) +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size) { - for (uint16_t i = 0; i < size; i++) + while ((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_DRE_Msk) != SERCOM_USART_INT_INTFLAG_DRE_Msk); + // Disable RX detec pin if needed + // Enable TX + LuosHAL_SetTxState(true); + + // Reduce size by one because we send one directly + data_size_to_transmit = size - 1; + if (size > 1) { - ctx.tx.lock = true; - while ((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_DRE_Msk) != SERCOM_USART_INT_INTFLAG_DRE_Msk); - LUOS_COM->USART_INT.SERCOM_DATA = *(data + i); - if (ctx.tx.collision) - { - // There is a collision - ctx.tx.collision = FALSE; - return 1; - } - LuosHAL_ResetTimeout(); + // Start the data buffer transmission + // **** NO DMA + //Copy the data pointer globally alowing to keep it and run the transmission. + tx_data = data; +#ifdef USE_TX_IT + // Send the first byte + LUOS_COM->USART_INT.SERCOM_DATA = *(tx_data++); + // Enable Transmission empty buffer interrupt to transmit next datas + LUOS_COM->USART_INT.SERCOM_INTENSET = SERCOM_USART_INT_INTENSET_DRE_Msk;//enable IT + // Disable Transmission complete interrupt + LUOS_COM->USART_INT.SERCOM_INTENCLR = SERCOM_USART_INT_INTENCLR_TXC_Msk;//disable IT +#else + data_size_to_transmit = 0;//to not check IT TC during collision + descriptor_section.DMAC_SRCADDR = (uint32_t)(data+size); + descriptor_section.DMAC_DSTADDR = (uint32_t)&LUOS_COM->USART_INT.SERCOM_DATA; + descriptor_section.DMAC_BTCNT = size; + LUOS_DMA->DMAC_CHCTRLA |= DMAC_CHCTRLA_ENABLE_Msk; + LUOS_COM->USART_INT.SERCOM_INTENSET = SERCOM_USART_INT_INTENSET_TXC_Msk;//enable IT +#endif } - LUOS_TIMER->COUNT16.TC_INTENCLR = TC_INTFLAG_OVF_Msk; - LUOS_COM->USART_INT.SERCOM_INTFLAG |= SERCOM_USART_EXT_INTFLAG_RXS(0); - return 0; -} -/****************************************************************************** - * @brief Luos Timeout for Tx communication - * @param None - * @return None - ******************************************************************************/ -void LuosHAL_ComTxComplete(void) -{ - while((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_TXC_Msk) != SERCOM_USART_INT_INTFLAG_TXC_Msk); - LuosHAL_ResetTimeout(); + else + { + // Transmit the only byte we have + LUOS_COM->USART_INT.SERCOM_DATA = *data; + // Enable Transmission complete interrupt because we only have one. + LUOS_COM->USART_INT.SERCOM_INTENSET = SERCOM_USART_INT_INTENSET_TXC_Msk;//enable IT + } + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } /****************************************************************************** * @brief set state of Txlock detection pin * @param None * @return Lock status ******************************************************************************/ -void LuosHAL_SetTxLockDetecState(uint8_t Enable) +void LuosHAL_SetRxDetecPin(uint8_t Enable) { if (TX_LOCK_DETECT_IRQ != DISABLE) { @@ -320,19 +377,26 @@ uint8_t LuosHAL_GetTxLockState(void) uint8_t result = false; if ((LUOS_COM->USART_INT.SERCOM_INTFLAG & SERCOM_USART_INT_INTFLAG_RXS_Msk) == SERCOM_USART_INT_INTFLAG_RXS_Msk) { - LUOS_COM->USART_INT.SERCOM_INTFLAG |= SERCOM_USART_EXT_INTFLAG_RXS(0); - LuosHAL_ResetTimeout(); + LUOS_COM->USART_INT.SERCOM_INTFLAG = SERCOM_USART_INT_INTFLAG_RXS_Msk; + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); result = true; } else { if ((TX_LOCK_DETECT_PIN != DISABLE) && (TX_LOCK_DETECT_PORT != DISABLE)) { + if(((PORT_REGS->GROUP[TX_LOCK_DETECT_PORT].PORT_IN >> TX_LOCK_DETECT_PIN) & 0x01) == 0x00) + { + result = true; + } if(TX_LOCK_DETECT_IRQ == DISABLE) { - result = ((PORT_REGS->GROUP[TX_LOCK_DETECT_PORT].PORT_IN >> TX_LOCK_DETECT_PIN) & 0x01); + if (result == true) + { + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + } } - } + } } return result; } @@ -344,17 +408,19 @@ uint8_t LuosHAL_GetTxLockState(void) static void LuosHAL_TimeoutInit(void) { //initialize clock - LUOS_TIMER_LOCK_ENABLE(); + LUOS_TIMER_CLOCK_ENABLE(); + LUOS_TIMER->COUNT16.TC_CTRLA = TC_CTRLA_RESETVALUE; while((LUOS_TIMER->COUNT16.TC_STATUS & TC_STATUS_SYNCBUSY_Msk)); /* Configure counter mode & prescaler */ LUOS_TIMER->COUNT16.TC_CTRLA = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_WAVEGEN_MPWM ; LUOS_TIMER->COUNT16.TC_CTRLBSET = TC_CTRLBSET_ONESHOT_Msk; - //LUOS_TIMER->COUNT16.TC_DBGCTRL = TC_DBGCTRL_DBGRUN_Msk; + LUOS_TIMER->COUNT16.TC_COUNT = 0xFFFF - (timoutclockcnt*DEFAULT_TIMEOUT); /* Clear all interrupt flags */ - LUOS_TIMER->COUNT16.TC_INTENSET = TC_INTFLAG_RESETVALUE; - + LUOS_TIMER->COUNT16.TC_INTENSET = TC_INTENSET_RESETVALUE; + LUOS_TIMER->COUNT16.TC_INTENSET = TC_INTENSET_OVF_Msk; + NVIC_SetPriority(LUOS_TIMER_IRQ, 3); NVIC_EnableIRQ(LUOS_TIMER_IRQ); } @@ -363,29 +429,33 @@ static void LuosHAL_TimeoutInit(void) * @param None * @return None ******************************************************************************/ -static void LuosHAL_ResetTimeout(void) +void LuosHAL_ResetTimeout(uint16_t nbrbit) { NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// clear IT pending - LUOS_TIMER->COUNT16.TC_INTFLAG |= TC_INTFLAG_OVF(0); - LUOS_TIMER->COUNT16.TC_COUNT = 0xFFFF - Timer_Reload; - LUOS_TIMER->COUNT16.TC_INTENSET = TC_INTFLAG_OVF_Msk; - LUOS_TIMER->COUNT16.TC_CTRLA |= TC_CTRLA_ENABLE_Msk; - while((LUOS_TIMER->COUNT16.TC_STATUS & TC_STATUS_SYNCBUSY_Msk)); + LUOS_TIMER->COUNT16.TC_INTFLAG = TC_INTFLAG_OVF_Msk;//clear flag + LUOS_TIMER->COUNT16.TC_CTRLA &= ~TC_CTRLA_ENABLE_Msk; + if(nbrbit != 0) + { + LUOS_TIMER->COUNT16.TC_COUNT = 0xFFFF - (timoutclockcnt*nbrbit); + LUOS_TIMER->COUNT16.TC_CTRLA |= TC_CTRLA_ENABLE_Msk; + } } /****************************************************************************** * @brief Luos Timeout for Rx communication * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComTimeout(void) +void LUOS_TIMER_IRQHANDLER() { if((LUOS_TIMER->COUNT16.TC_INTFLAG & TC_INTFLAG_OVF_Msk) == TC_INTFLAG_OVF_Msk) { - LUOS_TIMER->COUNT16.TC_INTFLAG |= TC_INTFLAG_OVF(0); - if (ctx.tx.lock == true) + LUOS_TIMER->COUNT16.TC_INTFLAG = TC_INTFLAG_OVF_Msk;//clear + if ((ctx.tx.lock == true)&&(LuosHAL_GetTxLockState() == false)) { + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); Recep_Timeout(); - } + } } } /****************************************************************************** @@ -403,28 +473,28 @@ static void LuosHAL_GPIOInit(void) if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : RxEN_Pin */ - PORT_REGS->GROUP[RX_EN_PORT].PORT_PINCFG[RX_EN_PIN] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT_REGS->GROUP[RX_EN_PORT].PORT_PINCFG[RX_EN_PIN] |= PORT_PINCFG_DRVSTR_Msk; //hight streght drive - PORT_REGS->GROUP[RX_EN_PORT].PORT_DIRSET = (1 << RX_EN_PIN); //Output - PORT_REGS->GROUP[RX_EN_PORT].PORT_OUTCLR = (1 << RX_EN_PIN); //disable Tx set output low - } + /*Configure GPIO pins : RxEN_Pin */ + PORT_REGS->GROUP[RX_EN_PORT].PORT_PINCFG[RX_EN_PIN] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght + PORT_REGS->GROUP[RX_EN_PORT].PORT_PINCFG[RX_EN_PIN] |= PORT_PINCFG_DRVSTR_Msk; //hight streght drive + PORT_REGS->GROUP[RX_EN_PORT].PORT_DIRSET = (1 << RX_EN_PIN); //Output + PORT_REGS->GROUP[RX_EN_PORT].PORT_OUTCLR = (1 << RX_EN_PIN); //disable Tx set output low + } if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : TxEN_Pin */ - PORT_REGS->GROUP[TX_EN_PORT].PORT_PINCFG[TX_EN_PIN] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT_REGS->GROUP[TX_EN_PORT].PORT_PINCFG[TX_EN_PIN] |= PORT_PINCFG_DRVSTR_Msk; //hight streght drive - PORT_REGS->GROUP[TX_EN_PORT].PORT_DIRSET = (1 << TX_EN_PIN); //Output - PORT_REGS->GROUP[TX_EN_PORT].PORT_OUTCLR = (1 << TX_EN_PIN); //disable Tx set output low - } + /*Configure GPIO pins : TxEN_Pin */ + PORT_REGS->GROUP[TX_EN_PORT].PORT_PINCFG[TX_EN_PIN] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght + PORT_REGS->GROUP[TX_EN_PORT].PORT_PINCFG[TX_EN_PIN] |= PORT_PINCFG_DRVSTR_Msk; //hight streght drive + PORT_REGS->GROUP[TX_EN_PORT].PORT_DIRSET = (1 << TX_EN_PIN); //Output + PORT_REGS->GROUP[TX_EN_PORT].PORT_OUTCLR = (1 << TX_EN_PIN); //disable Tx set output low + } /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) { - PORT_REGS->GROUP[TX_LOCK_DETECT_PORT].PORT_PINCFG[TX_LOCK_DETECT_PIN] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT_REGS->GROUP[TX_LOCK_DETECT_PORT].PORT_PINCFG[TX_LOCK_DETECT_PIN] |= PORT_PINCFG_INEN_Msk; //enable input - PORT_REGS->GROUP[TX_LOCK_DETECT_PORT].PORT_OUTSET = (1 << TX_LOCK_DETECT_PIN); //pull up + PORT_REGS->GROUP[TX_LOCK_DETECT_PORT].PORT_PINCFG[TX_LOCK_DETECT_PIN] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght + PORT_REGS->GROUP[TX_LOCK_DETECT_PORT].PORT_PINCFG[TX_LOCK_DETECT_PIN] |= PORT_PINCFG_INEN_Msk; //enable input + PORT_REGS->GROUP[TX_LOCK_DETECT_PORT].PORT_OUTSET = (1 << TX_LOCK_DETECT_PIN); //pull up if (TX_LOCK_DETECT_IRQ != DISABLE) { PORT_REGS->GROUP[TX_LOCK_DETECT_PORT].PORT_PMUX[TX_LOCK_DETECT_PIN>>1] |= (0<<(4*(TX_LOCK_DETECT_PIN%2))); @@ -432,7 +502,7 @@ static void LuosHAL_GPIOInit(void) { Config = 0; Position = TX_LOCK_DETECT_IRQ << 2; - + } else { @@ -448,15 +518,15 @@ static void LuosHAL_GPIOInit(void) /*Configure GPIO pin : TxPin */ PORT_REGS->GROUP[COM_TX_PORT].PORT_PINCFG[COM_TX_PIN] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT_REGS->GROUP[COM_TX_PORT].PORT_PINCFG[COM_TX_PIN] |= PORT_PINCFG_PULLEN; - PORT_REGS->GROUP[COM_TX_PORT].PORT_PINCFG[COM_TX_PIN] |= PORT_PINCFG_PMUXEN_Msk; //mux en + PORT_REGS->GROUP[COM_TX_PORT].PORT_PINCFG[COM_TX_PIN] |= PORT_PINCFG_PULLEN_Msk; + PORT_REGS->GROUP[COM_TX_PORT].PORT_PINCFG[COM_TX_PIN] |= PORT_PINCFG_PMUXEN_Msk; //mux en PORT_REGS->GROUP[COM_TX_PORT].PORT_PMUX[COM_TX_PIN>>1] |= (COM_TX_AF<<(4*(COM_TX_PIN%2))); //mux to sercom - + /*Configure GPIO pin : RxPin */ PORT_REGS->GROUP[COM_RX_PORT].PORT_PINCFG[COM_RX_PIN] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT_REGS->GROUP[COM_RX_PORT].PORT_PINCFG[COM_RX_PIN] |= PORT_PINCFG_PMUXEN_Msk; //mux en + PORT_REGS->GROUP[COM_RX_PORT].PORT_PINCFG[COM_RX_PIN] |= PORT_PINCFG_PMUXEN_Msk; //mux en PORT_REGS->GROUP[COM_RX_PORT].PORT_PMUX[COM_RX_PIN>>1] |= (COM_TX_AF<<(4*(COM_RX_PIN%2))); //mux to sercom - + //configure PTP LuosHAL_RegisterPTP(); for (uint8_t i = 0; i < NBR_PORT; i++) /*Configure GPIO pins : PTP_Pin */ @@ -465,15 +535,12 @@ static void LuosHAL_GPIOInit(void) PORT_REGS->GROUP[PTP[NBR_PORT].Port].PORT_PMUX[PTP[NBR_PORT].Pin>>1] |= (0<<(4*(PTP[NBR_PORT].Pin%2))); LuosHAL_SetPTPDefaultState(i); } - + NVIC_SetPriority(EIC_IRQn, 3); NVIC_EnableIRQ(EIC_IRQn); - + //Enable EIC interrupt EIC_REGS->EIC_CTRL |= EIC_CTRL_ENABLE_Msk; - - //while(EIC_REGS->EIC_STATUS.EIC_SYNCBUSY); - } /****************************************************************************** * @brief Register PTP @@ -511,21 +578,25 @@ static void LuosHAL_RegisterPTP(void) * @param GPIO IT line * @return None ******************************************************************************/ -static inline void LuosHAL_GPIOProcess(uint16_t GPIO) +void PINOUT_IRQHANDLER() { + uint32_t FlagIT = 0; ////Process for Tx Lock Detec - if (GPIO == TX_LOCK_DETECT_PIN) + if (((EIC_REGS->EIC_INTFLAG & (1 << TX_LOCK_DETECT_PIN)))&&(TX_LOCK_DETECT_IRQ == DISABLE)) { ctx.tx.lock = true; - LuosHAL_ResetTimeout(); - EIC_REGS->EIC_INTENCLR = (1 << TX_LOCK_DETECT_IRQ); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + EIC_REGS->EIC_INTFLAG = (uint32_t)(1 << TX_LOCK_DETECT_PIN); + EIC_REGS->EIC_INTENCLR = (1 << TX_LOCK_DETECT_PIN); } else { for (uint8_t i = 0; i < NBR_PORT; i++) { - if (GPIO == PTP[i].Pin) + FlagIT = (EIC_REGS->EIC_INTFLAG & (1 << PTP[i].Pin)); + if (FlagIT) { + EIC_REGS->EIC_INTFLAG = (uint32_t)(1 << PTP[i].Pin); PortMng_PtpHandler(i); break; } @@ -544,14 +615,14 @@ void LuosHAL_SetPTPDefaultState(uint8_t PTPNbr) // Pull Down / IT mode / Rising Edge PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_PMUXEN_Msk; //mux en + PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_PMUXEN_Msk; //mux en PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_PULLEN_Msk; //pull en PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_OUTCLR = (1 << PTP[PTPNbr].Pin); //pull down if(PTP[PTPNbr].Irq < 8) { Config = 0; Position = PTP[PTPNbr].Irq << 2; - + } else { @@ -574,14 +645,14 @@ void LuosHAL_SetPTPReverseState(uint8_t PTPNbr) uint32_t Config = 0; // Pull Down / IT mode / Falling Edge PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_PMUXEN_Msk; //mux en + PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_PMUXEN_Msk; //mux en PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_PULLEN_Msk; //pull en PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_OUTCLR = (1 << PTP[PTPNbr].Pin); //pull down if(PTP[PTPNbr].Irq < 8) { Config = 0; Position = PTP[PTPNbr].Irq << 2; - + } else { @@ -605,9 +676,9 @@ void LuosHAL_PushPTP(uint8_t PTPNbr) EIC_REGS->EIC_INTFLAG = (1 << PTP[PTPNbr].Irq); //clear IT flag PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght //PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_PULLEN_Msk; //pull en - PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_DIRSET = (1 << PTP[PTPNbr].Pin); //Output + PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_DIRSET = (1 << PTP[PTPNbr].Pin); //Output PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_OUTSET = (1 << PTP[PTPNbr].Pin); //pull down - + } /****************************************************************************** * @brief Get PTP line @@ -622,8 +693,8 @@ uint8_t LuosHAL_GetPTPState(uint8_t PTPNbr) PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_INEN_Msk; //input PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_PULLEN_Msk; //pull en - PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_DIRCLR = (1 << PTP[PTPNbr].Pin); //Output - PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_OUTCLR = (1 << PTP[PTPNbr].Pin); //pull down + PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_DIRCLR = (1 << PTP[PTPNbr].Pin); //Output + PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_OUTCLR = (1 << PTP[PTPNbr].Pin); //pull down return (((PORT_REGS->GROUP[PTP[PTPNbr].Port].PORT_IN >> PTP[PTPNbr].Pin)) & 0x01); } /****************************************************************************** @@ -642,17 +713,14 @@ static void LuosHAL_CRCInit(void) ******************************************************************************/ void LuosHAL_ComputeCRC(uint8_t *data, uint8_t *crc) { - for (uint8_t i = 0; i < 1; ++i) + uint16_t dbyte = *data; + *(uint16_t *)crc ^= dbyte << 8; + for (uint8_t j = 0; j < 8; ++j) { - uint16_t dbyte = data[i]; - *(uint16_t *)crc ^= dbyte << 8; - for (uint8_t j = 0; j < 8; ++j) - { - uint16_t mix = *(uint16_t *)crc & 0x8000; - *(uint16_t *)crc = (*(uint16_t *)crc << 1); - if (mix) - *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; - } + uint16_t mix = *(uint16_t *)crc & 0x8000; + *(uint16_t *)crc = (*(uint16_t *)crc << 1); + if (mix) + *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; } } /****************************************************************************** @@ -662,7 +730,7 @@ void LuosHAL_ComputeCRC(uint8_t *data, uint8_t *crc) ******************************************************************************/ static void LuosHAL_FlashInit(void) { - NVMCTRL_REGS->NVMCTRL_CTRLB = NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY | NVMCTRL_CTRLB_SLEEPPRM_WAKEONACCESS + NVMCTRL_REGS->NVMCTRL_CTRLB = NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY | NVMCTRL_CTRLB_SLEEPPRM_WAKEONACCESS | NVMCTRL_CTRLB_RWS(1) | NVMCTRL_CTRLB_MANW_Msk; } /****************************************************************************** @@ -691,7 +759,7 @@ void LuosHAL_FlashWriteLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *dat { uint32_t i = 0; uint32_t * paddress = (uint32_t *)addr; - + // Before writing we have to erase the entire page // to do that we have to backup current falues by copying it into RAM uint8_t page_backup[16 * PAGE_SIZE]; @@ -725,29 +793,4 @@ void LuosHAL_FlashReadLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *data memcpy(data, (void *)(addr), size); } -/////////////////////////Special LuosHAL function/////////////////////////// -void PINOUT_IRQHANDLER() -{ - uint32_t FlagIT = 0; - for (uint8_t i = 0; i < NBR_PORT; i++) - { - FlagIT = (EIC_REGS->EIC_INTFLAG & (1 << PTP[i].Pin)); - - if (FlagIT) - { - LuosHAL_GPIOProcess(PTP[i].Pin); - EIC_REGS->EIC_INTFLAG = (uint32_t)(1 << PTP[i].Pin); - } - } -} -void LUOS_COM_IRQHANDLER() -{ - LuosHAL_ComReceive(); -} - -void LUOS_TIMER_IRQHANDLER() -{ - LuosHAL_ComTimeout(); -} - diff --git a/ATSAMD21/luos_hal.h b/ATSAMD21/luos_hal.h index 27c9f43..b5ab318 100644 --- a/ATSAMD21/luos_hal.h +++ b/ATSAMD21/luos_hal.h @@ -32,10 +32,10 @@ uint32_t LuosHAL_GetSystick(void); void LuosHAL_ComInit(uint32_t Baudrate); void LuosHAL_SetTxState(uint8_t Enable); void LuosHAL_SetRxState(uint8_t Enable); -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size); -void LuosHAL_SetTxLockDetecState(uint8_t Enable); +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size); uint8_t LuosHAL_GetTxLockState(void); -void LuosHAL_ComTxComplete(void); +void LuosHAL_SetRxDetecPin(uint8_t Enable); +void LuosHAL_ResetTimeout(uint16_t nbrbit); void LuosHAL_SetPTPDefaultState(uint8_t PTPNbr); void LuosHAL_SetPTPReverseState(uint8_t PTPNbr); void LuosHAL_PushPTP(uint8_t PTPNbr); diff --git a/ATSAMD21/luos_hal_config.h b/ATSAMD21/luos_hal_config.h index ad81754..5277522 100644 --- a/ATSAMD21/luos_hal_config.h +++ b/ATSAMD21/luos_hal_config.h @@ -12,6 +12,8 @@ #include "samd21.h" +//If your MCU do not Have DMA for tx transmit define USE_TX_IT + #define DISABLE 0x00 #ifndef MCUFREQ @@ -132,11 +134,30 @@ #ifndef LUOS_COM_IRQHANDLER #define LUOS_COM_IRQHANDLER() SERCOM0_Handler() #endif +/******************************************************************************* + * DMA CONFIG + ******************************************************************************/ +#ifndef LUOS_DMA_CLOCK_ENABLE +#define LUOS_DMA_CLOCK_ENABLE() \ + do \ + { \ + PM_REGS->PM_AHBMASK |= PM_AHBMASK_DMAC_Msk; \ + } while (0U) +#endif +#ifndef LUOS_DMA +#define LUOS_DMA DMAC_REGS +#endif +#ifndef LUOS_DMA_TRIGGER +#define LUOS_DMA_TRIGGER 2 +#endif +#ifndef LUOS_DMA_CHANNEL +#define LUOS_DMA_CHANNEL 0 +#endif /******************************************************************************* * COM TIMEOUT CONFIG ******************************************************************************/ -#ifndef LUOS_TIMER_LOCK_ENABLE -#define LUOS_TIMER_LOCK_ENABLE() \ +#ifndef LUOS_TIMER_CLOCK_ENABLE +#define LUOS_TIMER_CLOCK_ENABLE() \ do \ { \ GCLK_REGS->GCLK_CLKCTRL = GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_TCC2_TC3_Val) | GCLK_CLKCTRL_GEN(0x0) | GCLK_CLKCTRL_CLKEN_Msk; \ diff --git a/ATSAMD21_ARDUINO/board_config.h b/ATSAMD21_ARDUINO/board_config.h index 1575f54..80c555b 100644 --- a/ATSAMD21_ARDUINO/board_config.h +++ b/ATSAMD21_ARDUINO/board_config.h @@ -12,31 +12,33 @@ #include -#ifdef ARDUINO_SAMD_ZERO -#define LUOS_COM_CLOCK_ENABLE() \ - do \ - { \ - GCLK->CLKCTRL.reg = \ - (uint16_t)(GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_SERCOM0_CORE_Val) | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN); \ - PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0; \ - } while (0U) -#define LUOS_COM SERCOM0 -#define LUOS_COM_IRQ SERCOM0_IRQn -#define LUOS_COM_IRQHANDLER() SERCOM0_Handler() +#if defined(ARDUINO_SAMD_ZERO) + #define LUOS_COM_CLOCK_ENABLE() \ + do \ + { \ + GCLK->CLKCTRL.reg = \ + (uint16_t)(GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_SERCOM0_CORE_Val) | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN); \ + PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0; \ + } while (0U) + #define LUOS_COM SERCOM0 + #define LUOS_COM_IRQ SERCOM0_IRQn + #define LUOS_COM_IRQHANDLER() SERCOM0_Handler() #endif -#if defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) \ -|| defined(ARDUINO_SAMD_MKRWAN1310)|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) -. - do \ - { \ - GCLK->CLKCTRL.reg = \ - (uint16_t)(GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_SERCOM5_CORE_Val) | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN); \ - PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5 \ - } while (0U) -#define LUOS_COM SERCOM5 -#define LUOS_COM_IRQ SERCOM5_IRQn -#define LUOS_COM_IRQHANDLER() SERCOM5_Handler() +#if (defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_MKRFox1200) \ + || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310)|| defined(ARDUINO_SAMD_MKRGSM1400) \ + || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRZERO) || defined(ARDUINO_SAMD_NANO_33_IOT) \ + || defined(SAMD_MKRVIDOR4000)) + #define LUOS_COM_CLOCK_ENABLE()\ + do \ + { \ + GCLK->CLKCTRL.reg = \ + (uint16_t)(GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_SERCOM5_CORE_Val) | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN); \ + PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5; \ + } while (0U) + #define LUOS_COM SERCOM5 + #define LUOS_COM_IRQ SERCOM5_IRQn + #define LUOS_COM_IRQHANDLER() SERCOM5_Handler() #endif #endif /* _BOARD_CONFIG_H_ */ diff --git a/ATSAMD21_ARDUINO/luos_hal.c b/ATSAMD21_ARDUINO/luos_hal.c index 14692a9..a5d06f1 100644 --- a/ATSAMD21_ARDUINO/luos_hal.c +++ b/ATSAMD21_ARDUINO/luos_hal.c @@ -1,6 +1,6 @@ /****************************************************************************** * @file luosHAL - * @brief Luos Hardware Abstration Layer. Describe Low layer fonction + * @brief Luos Hardware Abstration Layer. Describe Low layer fonction * @MCU Family ATSAMD21 * @author Luos * @version 0.0.0 @@ -18,11 +18,12 @@ /******************************************************************************* * Definitions ******************************************************************************/ -uint8_t test = 0; +#define DEFAULT_TIMEOUT 20 + /******************************************************************************* * Variables ******************************************************************************/ -uint32_t Timer_Reload = ((MCUFREQ /DEFAULTBAUDRATE)*20); //20us//2*10bits +volatile uint32_t tick; typedef struct { @@ -32,6 +33,15 @@ typedef struct } Port_t; Port_t PTP[NBR_PORT]; + +volatile uint16_t timoutclockcnt = 0; +volatile uint16_t data_size_to_transmit = 0; +volatile uint8_t *tx_data = 0; + +#ifndef USE_TX_IT +static DmacDescriptor write_back_section; +static DmacDescriptor descriptor_section; +#endif /******************************************************************************* * Function ******************************************************************************/ @@ -39,12 +49,8 @@ static void LuosHAL_SystickInit(void); static void LuosHAL_FlashInit(void); static void LuosHAL_CRCInit(void); static void LuosHAL_TimeoutInit(void); -static void LuosHAL_ResetTimeout(void); -static inline void LuosHAL_ComTimeout(void); static void LuosHAL_GPIOInit(void); static void LuosHAL_FlashEraseLuosMemoryInfo(void); -static inline void LuosHAL_ComReceive(void); -static inline void LuosHAL_GPIOProcess(uint16_t GPIO); static void LuosHAL_RegisterPTP(void); /////////////////////////Luos Library Needed function/////////////////////////// @@ -58,7 +64,7 @@ void LuosHAL_Init(void) { //Systick Initialization LuosHAL_SystickInit(); - + //IO Initialization LuosHAL_GPIOInit(); @@ -95,9 +101,9 @@ void LuosHAL_SetIrqState(uint8_t Enable) static void LuosHAL_SystickInit(void) { SysTick->CTRL = 0; - SysTick->VAL = 0; - SysTick->LOAD = 0xbb80 - 1; - SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_CLKSOURCE_Msk; + SysTick->VAL = 0; + SysTick->LOAD = 0xbb80 - 1; + SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_CLKSOURCE_Msk; SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; } /****************************************************************************** @@ -123,21 +129,21 @@ void LuosHAL_ComInit(uint32_t Baudrate) /* Disable the USART before configurations */ LUOS_COM->USART.CTRLA.reg &= ~SERCOM_USART_CTRLA_ENABLE; + /* Configure Baud Rate */ + baud = 65536 - ((uint64_t)65536 * 16 * Baudrate) / MCUFREQ; + LUOS_COM->USART.BAUD.reg = SERCOM_USART_BAUD_BAUD(baud); + //Configures USART Clock Mode/ TXPO and RXPO/ Data Order/ Standby Mode/ Sampling rate/ IBON - LUOS_COM->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE_USART_INT_CLK | SERCOM_USART_CTRLA_RXPO(COM_RX_POS) - | SERCOM_USART_CTRLA_TXPO(COM_TX_POS) | SERCOM_USART_CTRLA_DORD - | SERCOM_USART_CTRLA_IBON | SERCOM_USART_CTRLA_FORM(0x0) + LUOS_COM->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE_USART_INT_CLK | SERCOM_USART_CTRLA_RXPO(COM_RX_POS) + | SERCOM_USART_CTRLA_TXPO(COM_TX_POS) | SERCOM_USART_CTRLA_DORD + | SERCOM_USART_CTRLA_IBON | SERCOM_USART_CTRLA_FORM(0x0) | SERCOM_USART_CTRLA_SAMPR(0) ; - + //Configures RXEN/ TXEN/ CHSIZE/ Parity/ Stop bits - LUOS_COM->USART.CTRLB.reg = SERCOM_USART_CTRLB_CHSIZE(0) | SERCOM_USART_CTRLB_SBMODE - | SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN + LUOS_COM->USART.CTRLB.reg = SERCOM_USART_CTRLB_CHSIZE(0) | SERCOM_USART_CTRLB_SBMODE + | SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_SFDE; - /* Configure Baud Rate */ - baud = 65536 - ((uint64_t)65536 * 16 * Baudrate) / MCUFREQ; - LUOS_COM->USART.BAUD.reg = SERCOM_USART_BAUD_BAUD(baud); - /* Enable the UART after the configurations */ LUOS_COM->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE; @@ -146,19 +152,28 @@ void LuosHAL_ComInit(uint32_t Baudrate) /* Clean IT */ LUOS_COM->USART.INTENSET.reg = SERCOM_USART_INTENSET_RESETVALUE; - - /* Enable error interrupt */ - LUOS_COM->USART.INTENSET.reg = SERCOM_USART_INTENSET_ERROR; /* Enable Receive Complete interrupt */ LUOS_COM->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC; - + NVIC_SetPriority(LUOS_COM_IRQ, 3); NVIC_EnableIRQ(LUOS_COM_IRQ); //Timeout Initialization - Timer_Reload = ((MCUFREQ /Baudrate)*20); //20us//2*10bits + timoutclockcnt = MCUFREQ /Baudrate; LuosHAL_TimeoutInit(); + +#ifndef USE_TX_IT + LUOS_DMA_CLOCK_ENABLE(); + + LUOS_DMA->BASEADDR.reg = (uint32_t)&descriptor_section; + LUOS_DMA->WRBADDR.reg = (uint32_t)&write_back_section; + LUOS_DMA->PRICTRL0.reg = DMAC_PRICTRL0_LVLPRI0(1UL) | DMAC_PRICTRL0_RRLVLEN0 | DMAC_PRICTRL0_LVLPRI1(1UL) | DMAC_PRICTRL0_RRLVLEN1 | DMAC_PRICTRL0_LVLPRI2(1UL) | DMAC_PRICTRL0_RRLVLEN2 | DMAC_PRICTRL0_LVLPRI3(1UL) | DMAC_PRICTRL0_RRLVLEN3; + LUOS_DMA->CHID.reg = LUOS_DMA_CHANNEL;//DMA Channel + LUOS_DMA->CHCTRLB.reg = DMAC_CHCTRLB_TRIGACT(2) | DMAC_CHCTRLB_TRIGSRC(LUOS_DMA_TRIGGER) | DMAC_CHCTRLB_LVL(0) ; + descriptor_section.BTCTRL.reg = DMAC_BTCTRL_BLOCKACT_INT | DMAC_BTCTRL_BEATSIZE_BYTE | DMAC_BTCTRL_VALID | DMAC_BTCTRL_SRCINC ; + LUOS_DMA->CTRL.reg = DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN0 | DMAC_CTRL_LVLEN1 | DMAC_CTRL_LVLEN2 | DMAC_CTRL_LVLEN3; +#endif } /****************************************************************************** * @brief Tx enable/disable relative to com @@ -171,17 +186,27 @@ void LuosHAL_SetTxState(uint8_t Enable) { PORT->Group[COM_TX_PORT].PINCFG[COM_TX_PIN].reg &= ~PORT_PINCFG_PULLEN; //Tx push pull if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - PORT->Group[TX_EN_PORT].OUTSET.reg = (1 << TX_EN_PIN); //enable Tx - } + { + PORT->Group[TX_EN_PORT].OUTSET.reg = (1 << TX_EN_PIN); //enable Tx + } } else { PORT->Group[COM_TX_PORT].PINCFG[COM_TX_PIN].reg |= PORT_PINCFG_PULLEN; //Tx open drain if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - PORT->Group[TX_EN_PORT].OUTCLR.reg = (1 << TX_EN_PIN); //disable Tx + { + PORT->Group[TX_EN_PORT].OUTCLR.reg = (1 << TX_EN_PIN); //disable Tx } +#ifdef USE_TX_IT + // Stop current transmit operation + data_size_to_transmit = 0; + // Disable Transmission empty buffer interrupt + LUOS_COM->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE;//disable IT +#else + LUOS_DMA->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE; +#endif + // Disable Transmission complete interrupt + LUOS_COM->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_TXC;//disable IT LUOS_COM->USART.INTFLAG.bit.RXS = 1;//clear flag rx start } } @@ -196,18 +221,12 @@ void LuosHAL_SetRxState(uint8_t Enable) { LUOS_COM->USART.DATA.reg; LUOS_COM->USART.CTRLB.reg |= SERCOM_USART_CTRLB_RXEN; - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - PORT->Group[RX_EN_PORT].OUTCLR.reg = (1 << RX_EN_PIN); //enable rx - } + LUOS_COM->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC; } else { - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - PORT->Group[RX_EN_PORT].OUTSET.reg = (1 << RX_EN_PIN); //disable rx - } LUOS_COM->USART.CTRLB.reg &= ~SERCOM_USART_CTRLB_RXEN; + LUOS_COM->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_RXC; } } /****************************************************************************** @@ -215,34 +234,62 @@ void LuosHAL_SetRxState(uint8_t Enable) * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComReceive(void) +void LUOS_COM_IRQHANDLER() { - uint8_t data = 0; + // Reset timeout to it's default value + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); - LuosHAL_ResetTimeout(); - - // check if we receive a data - if((LUOS_COM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) == SERCOM_USART_INTFLAG_RXC) + // reception management + if(((LUOS_COM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) == SERCOM_USART_INTFLAG_RXC)&& + ((LUOS_COM->USART.INTENSET.reg & SERCOM_USART_INTENSET_RXC) == SERCOM_USART_INTENSET_RXC)) { //clean start bit detection - data = LUOS_COM->USART.DATA.reg; + uint8_t data = LUOS_COM->USART.DATA.reg; ctx.rx.callback(&data); + if (data_size_to_transmit == 0) + { + LUOS_COM->USART.STATUS.reg = SERCOM_USART_STATUS_PERR | SERCOM_USART_STATUS_FERR | SERCOM_USART_STATUS_BUFOVF; + LUOS_COM->USART.INTFLAG.bit.RXS = 1;//clear flag rx start + return; + } } - // check error on ligne - else if((LUOS_COM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_ERROR) == SERCOM_USART_INTFLAG_ERROR) + + else if((LUOS_COM->USART.STATUS.reg & SERCOM_USART_STATUS_FERR) == SERCOM_USART_STATUS_FERR) // check error on ligne { - if((LUOS_COM->USART.STATUS.reg & SERCOM_USART_STATUS_FERR) == SERCOM_USART_STATUS_FERR) - { - ctx.rx.status.rx_framing_error = true; - } - LUOS_COM->USART.STATUS.reg = SERCOM_USART_STATUS_PERR | SERCOM_USART_STATUS_FERR | SERCOM_USART_STATUS_BUFOVF; - LUOS_COM->USART.INTFLAG.reg |= SERCOM_USART_INTENCLR_ERROR; - - while((LUOS_COM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) == SERCOM_USART_INTFLAG_RXC) + ctx.rx.status.rx_framing_error = true; + } + + // Transmission management + if(((LUOS_COM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == SERCOM_USART_INTFLAG_TXC)&& + ((LUOS_COM->USART.INTENSET.reg & SERCOM_USART_INTENSET_TXC) == SERCOM_USART_INTENSET_TXC)) + { + // Transmission complete + // Switch to reception mode + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); + // Disable transmission complete IRQ + LUOS_COM->USART.INTFLAG.reg = SERCOM_USART_INTFLAG_TXC;//clear flag + LUOS_COM->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_TXC;//disable IT + } +#ifdef USE_TX_IT + else if(((LUOS_COM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) == SERCOM_USART_INTFLAG_DRE)&& + ((LUOS_COM->USART.INTENSET.reg & SERCOM_USART_INTENSET_DRE) == SERCOM_USART_INTENSET_DRE)) + { + // Transmit buffer empty (this is a software DMA) + data_size_to_transmit--; + LUOS_COM->USART.DATA.reg = *(tx_data++); + if (data_size_to_transmit == 0) { - data = LUOS_COM->USART.DATA.reg; + // Transmission complete, stop loading data and watch for the end of transmission + // Disable Transmission empty buffer interrupt + LUOS_COM->USART.INTFLAG.reg = SERCOM_USART_INTFLAG_DRE;//clear flag + LUOS_COM->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE;//disable IT + // Enable Transmission complete interrupt + LUOS_COM->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC;//disable IT } } +#endif + LUOS_COM->USART.STATUS.reg = SERCOM_USART_STATUS_PERR | SERCOM_USART_STATUS_FERR | SERCOM_USART_STATUS_BUFOVF; LUOS_COM->USART.INTFLAG.bit.RXS = 1;//clear flag rx start } /****************************************************************************** @@ -250,41 +297,52 @@ static inline void LuosHAL_ComReceive(void) * @param None * @return None ******************************************************************************/ -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size) +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size) { - for (uint16_t i = 0; i < size; i++) + while ((LUOS_COM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) != SERCOM_USART_INTFLAG_DRE); + // Disable RX detec pin if needed + // Enable TX + LuosHAL_SetTxState(true); + + // Reduce size by one because we send one directly + data_size_to_transmit = size - 1; + if (size > 1) { - ctx.tx.lock = true; - while ((LUOS_COM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) != SERCOM_USART_INTFLAG_DRE); - LUOS_COM->USART.DATA.reg= *(data + i); - if (ctx.tx.collision) - { - // There is a collision - ctx.tx.collision = FALSE; - return 1; - } - LuosHAL_ResetTimeout(); + // Start the data buffer transmission + // **** NO DMA + //Copy the data pointer globally alowing to keep it and run the transmission. + tx_data = data; +#ifdef USE_TX_IT + // Send the first byte + LUOS_COM->USART.DATA.reg = *(tx_data++); + // Enable Transmission empty buffer interrupt to transmit next datas + LUOS_COM->USART.INTENSET.reg = SERCOM_USART_INTENSET_DRE;//enable IT + // Disable Transmission complete interrupt + LUOS_COM->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_TXC;//disable IT +#else + data_size_to_transmit = 0;//to not check IT TC during collision + descriptor_section.SRCADDR.reg = (uint32_t)(data+size); + descriptor_section.DSTADDR.reg = (uint32_t)&LUOS_COM->USART.DATA.reg; + descriptor_section.BTCNT.reg = size; + LUOS_DMA->CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; + LUOS_COM->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC;//enable IT +#endif } - LUOS_TIMER->COUNT16.INTENCLR.reg = TC_INTFLAG_OVF; - LUOS_COM->USART.INTFLAG.bit.RXS = 1;//clear flag rx start - return 0; -} -/****************************************************************************** - * @brief Luos Timeout for Tx communication - * @param None - * @return None - ******************************************************************************/ -void LuosHAL_ComTxComplete(void) -{ - while((LUOS_COM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) != SERCOM_USART_INTFLAG_TXC); - LuosHAL_ResetTimeout(); + else + { + // Transmit the only byte we have + LUOS_COM->USART.DATA.reg = *data; + // Enable Transmission complete interrupt because we only have one. + LUOS_COM->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC;//enable IT + } + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } /****************************************************************************** * @brief set state of Txlock detection pin * @param None * @return Lock status ******************************************************************************/ -void LuosHAL_SetTxLockDetecState(uint8_t Enable) +void LuosHAL_SetRxDetecPin(uint8_t Enable) { if (TX_LOCK_DETECT_IRQ != DISABLE) { @@ -310,18 +368,25 @@ uint8_t LuosHAL_GetTxLockState(void) if (LUOS_COM->USART.INTFLAG.bit.RXS == 1) { LUOS_COM->USART.INTFLAG.bit.RXS = 1;//clear flag rx start - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); result = true; } else { if ((TX_LOCK_DETECT_PIN != DISABLE) && (TX_LOCK_DETECT_PORT != DISABLE)) { + if(((PORT->Group[TX_LOCK_DETECT_PORT].IN.reg >> TX_LOCK_DETECT_PIN) & 0x01) == 0x00) + { + result = true; + } if(TX_LOCK_DETECT_IRQ == DISABLE) { - result = ((PORT->Group[TX_LOCK_DETECT_PORT].IN.reg >> TX_LOCK_DETECT_PIN) & 0x01); + if (result == true) + { + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + } } - } + } } return result; } @@ -341,10 +406,11 @@ static void LuosHAL_TimeoutInit(void) LUOS_TIMER->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_WAVEGEN_MPWM ; LUOS_TIMER->COUNT16.CTRLBSET.bit.ONESHOT = 1; - //LUOS_TIMER->COUNT16.DBGCTRL.reg = TC_DBGCTRL_DBGRUN; + LUOS_TIMER->COUNT16.COUNT.reg = 0xFFFF - (timoutclockcnt*DEFAULT_TIMEOUT); /* Clear all interrupt flags */ - LUOS_TIMER->COUNT16.INTENSET.reg = TC_INTFLAG_RESETVALUE; - + LUOS_TIMER->COUNT16.INTENSET.reg = TC_INTENSET_RESETVALUE; + LUOS_TIMER->COUNT16.INTENSET.reg = TC_INTENSET_OVF; + NVIC_SetPriority(LUOS_TIMER_IRQ, 3); NVIC_EnableIRQ(LUOS_TIMER_IRQ); } @@ -353,29 +419,33 @@ static void LuosHAL_TimeoutInit(void) * @param None * @return None ******************************************************************************/ -static void LuosHAL_ResetTimeout(void) +void LuosHAL_ResetTimeout(uint16_t nbrbit) { NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// clear IT pending LUOS_TIMER->COUNT16.INTFLAG.bit.OVF = 1; - LUOS_TIMER->COUNT16.COUNT.reg = 0xFFFF - (uint16_t)Timer_Reload; - LUOS_TIMER->COUNT16.INTENSET.reg = TC_INTFLAG_OVF; - LUOS_TIMER->COUNT16.CTRLA.bit.ENABLE = 1; - while((LUOS_TIMER->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY)); + LUOS_TIMER->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE; + if(nbrbit != 0) + { + LUOS_TIMER->COUNT16.COUNT.reg = 0xFFFF - (timoutclockcnt*nbrbit); + LUOS_TIMER->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; + } } /****************************************************************************** * @brief Luos Timeout for Rx communication * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComTimeout(void) +void LUOS_TIMER_IRQHANDLER() { if(LUOS_TIMER->COUNT16.INTFLAG.bit.OVF == 1) { LUOS_TIMER->COUNT16.INTFLAG.bit.OVF = 1; - if (ctx.tx.lock == true) + if ((ctx.tx.lock == true)&&(LuosHAL_GetTxLockState() == false)) { + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); Recep_Timeout(); - } + } } } /****************************************************************************** @@ -393,28 +463,28 @@ static void LuosHAL_GPIOInit(void) if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : RxEN_Pin */ - PORT->Group[RX_EN_PORT].PINCFG[RX_EN_PIN].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT->Group[RX_EN_PORT].PINCFG[RX_EN_PIN].reg |= PORT_PINCFG_DRVSTR; //hight streght drive - PORT->Group[RX_EN_PORT].DIRSET.reg = (1 << RX_EN_PIN); //Output - PORT->Group[RX_EN_PORT].OUTCLR.reg = (1 << RX_EN_PIN); //disable Tx set output low - } + /*Configure GPIO pins : RxEN_Pin */ + PORT->Group[RX_EN_PORT].PINCFG[RX_EN_PIN].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght + PORT->Group[RX_EN_PORT].PINCFG[RX_EN_PIN].reg |= PORT_PINCFG_DRVSTR; //hight streght drive + PORT->Group[RX_EN_PORT].DIRSET.reg = (1 << RX_EN_PIN); //Output + PORT->Group[RX_EN_PORT].OUTCLR.reg = (1 << RX_EN_PIN); //disable Tx set output low + } if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : TxEN_Pin */ - PORT->Group[TX_EN_PORT].PINCFG[TX_EN_PIN].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT->Group[TX_EN_PORT].PINCFG[TX_EN_PIN].reg |= PORT_PINCFG_DRVSTR; //hight streght drive - PORT->Group[TX_EN_PORT].DIRSET.reg = (1 << TX_EN_PIN); //Output - PORT->Group[TX_EN_PORT].OUTCLR.reg = (1 << TX_EN_PIN); //disable Tx set output low - } + /*Configure GPIO pins : TxEN_Pin */ + PORT->Group[TX_EN_PORT].PINCFG[TX_EN_PIN].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght + PORT->Group[TX_EN_PORT].PINCFG[TX_EN_PIN].reg |= PORT_PINCFG_DRVSTR; //hight streght drive + PORT->Group[TX_EN_PORT].DIRSET.reg = (1 << TX_EN_PIN); //Output + PORT->Group[TX_EN_PORT].OUTCLR.reg = (1 << TX_EN_PIN); //disable Tx set output low + } /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) { - PORT->Group[TX_LOCK_DETECT_PORT].PINCFG[TX_LOCK_DETECT_PIN].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT->Group[TX_LOCK_DETECT_PORT].PINCFG[TX_LOCK_DETECT_PIN].reg |= PORT_PINCFG_INEN; //enable input - PORT->Group[TX_LOCK_DETECT_PORT].OUTSET.reg = (1 << TX_LOCK_DETECT_PIN); //pull up + PORT->Group[TX_LOCK_DETECT_PORT].PINCFG[TX_LOCK_DETECT_PIN].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght + PORT->Group[TX_LOCK_DETECT_PORT].PINCFG[TX_LOCK_DETECT_PIN].reg |= PORT_PINCFG_INEN; //enable input + PORT->Group[TX_LOCK_DETECT_PORT].OUTSET.reg = (1 << TX_LOCK_DETECT_PIN); //pull up if (TX_LOCK_DETECT_IRQ != DISABLE) { PORT->Group[TX_LOCK_DETECT_PORT].PMUX[TX_LOCK_DETECT_PIN>>1].reg |= (0<<(4*(TX_LOCK_DETECT_PIN%2))); @@ -422,7 +492,7 @@ static void LuosHAL_GPIOInit(void) { Config = 0; Position = TX_LOCK_DETECT_IRQ << 2; - + } else { @@ -438,15 +508,15 @@ static void LuosHAL_GPIOInit(void) /*Configure GPIO pin : TxPin */ PORT->Group[COM_TX_PORT].PINCFG[COM_TX_PIN].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT->Group[COM_TX_PORT].PINCFG[COM_TX_PIN].reg |= PORT_PINCFG_PMUXEN; //mux en + PORT->Group[COM_TX_PORT].PINCFG[COM_TX_PIN].reg |= PORT_PINCFG_PMUXEN; //mux en PORT->Group[COM_TX_PORT].PINCFG[COM_TX_PIN].reg |= PORT_PINCFG_PULLEN; //Tx open drain PORT->Group[COM_TX_PORT].PMUX[COM_TX_PIN>>1].reg |= (COM_TX_AF<<(4*(COM_TX_PIN%2))); //mux to sercom - + /*Configure GPIO pin : RxPin */ PORT->Group[COM_RX_PORT].PINCFG[COM_RX_PIN].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT->Group[COM_RX_PORT].PINCFG[COM_RX_PIN].reg |= PORT_PINCFG_PMUXEN; //mux en + PORT->Group[COM_RX_PORT].PINCFG[COM_RX_PIN].reg |= PORT_PINCFG_PMUXEN; //mux en PORT->Group[COM_RX_PORT].PMUX[COM_RX_PIN>>1].reg |= (COM_TX_AF<<(4*(COM_RX_PIN%2))); //mux to sercom - + //configure PTP LuosHAL_RegisterPTP(); for (uint8_t i = 0; i < NBR_PORT; i++) /*Configure GPIO pins : PTP_Pin */ @@ -455,14 +525,12 @@ static void LuosHAL_GPIOInit(void) PORT->Group[PTP[NBR_PORT].Port].PMUX[PTP[NBR_PORT].Pin>>1].reg |= (0<<(4*(PTP[NBR_PORT].Pin%2))); LuosHAL_SetPTPDefaultState(i); } - + NVIC_SetPriority(EIC_IRQn, 3); NVIC_EnableIRQ(EIC_IRQn); //Enable EIC interrupt EIC->CTRL.reg |= EIC_CTRL_ENABLE; - - while (EIC->STATUS.bit.SYNCBUSY == 1); } /****************************************************************************** * @brief Register PTP @@ -500,21 +568,25 @@ static void LuosHAL_RegisterPTP(void) * @param GPIO IT line * @return None ******************************************************************************/ -static inline void LuosHAL_GPIOProcess(uint16_t GPIO) +void PINOUT_IRQHANDLER() { + uint32_t FlagIT = 0; ////Process for Tx Lock Detec - if (GPIO == TX_LOCK_DETECT_PIN) + if (((EIC->INTFLAG.reg & (1 << TX_LOCK_DETECT_PIN)))&&(TX_LOCK_DETECT_IRQ != DISABLE)) { ctx.tx.lock = true; - LuosHAL_ResetTimeout(); - EIC->INTENCLR.reg = (1 << TX_LOCK_DETECT_IRQ); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + EIC->INTFLAG.reg = (uint32_t)(1 << TX_LOCK_DETECT_PIN); + EIC->INTENCLR.reg = (1 << TX_LOCK_DETECT_PIN); } else { for (uint8_t i = 0; i < NBR_PORT; i++) { - if (GPIO == PTP[i].Pin) + FlagIT = (EIC->INTFLAG.reg& (1 << PTP[i].Pin)); + if (FlagIT) { + EIC->INTFLAG.reg = (uint32_t)(1 << PTP[i].Pin); PortMng_PtpHandler(i); break; } @@ -533,14 +605,14 @@ void LuosHAL_SetPTPDefaultState(uint8_t PTPNbr) // Pull Down / IT mode / Rising Edge PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg |= PORT_PINCFG_PMUXEN; //mux en + PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg |= PORT_PINCFG_PMUXEN; //mux en PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg |= PORT_PINCFG_PULLEN; //pull en PORT->Group[PTP[PTPNbr].Port].OUTCLR.reg = (1 << PTP[PTPNbr].Pin); //pull down if(PTP[PTPNbr].Irq < 8) { Config = 0; Position = PTP[PTPNbr].Irq << 2; - + } else { @@ -564,7 +636,7 @@ void LuosHAL_SetPTPReverseState(uint8_t PTPNbr) // Pull Down / IT mode / Falling Edge PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght - PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg |= PORT_PINCFG_PMUXEN; //mux en + PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg |= PORT_PINCFG_PMUXEN; //mux en PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg |= PORT_PINCFG_PULLEN; //pull en PORT->Group[PTP[PTPNbr].Port].OUTCLR.reg = (1 << PTP[PTPNbr].Pin); //pull down if(PTP[PTPNbr].Irq < 8) @@ -594,9 +666,9 @@ void LuosHAL_PushPTP(uint8_t PTPNbr) EIC->INTFLAG.reg = (1 << PTP[PTPNbr].Irq); //clear IT flag PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght //PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin] |= PORT_PINCFG_PULLEN; //pull en - PORT->Group[PTP[PTPNbr].Port].DIRSET.reg = (1 << PTP[PTPNbr].Pin); //Output + PORT->Group[PTP[PTPNbr].Port].DIRSET.reg = (1 << PTP[PTPNbr].Pin); //Output PORT->Group[PTP[PTPNbr].Port].OUTSET.reg = (1 << PTP[PTPNbr].Pin); //pull down - + } /****************************************************************************** * @brief Get PTP line @@ -611,8 +683,8 @@ uint8_t LuosHAL_GetPTPState(uint8_t PTPNbr) PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg = PORT_PINCFG_RESETVALUE; //no pin mux / no input / no pull / low streght PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg |= PORT_PINCFG_INEN; //input PORT->Group[PTP[PTPNbr].Port].PINCFG[PTP[PTPNbr].Pin].reg |= PORT_PINCFG_PULLEN; //pull en - PORT->Group[PTP[PTPNbr].Port].DIRCLR.reg = (1 << PTP[PTPNbr].Pin); //Output - PORT->Group[PTP[PTPNbr].Port].OUTCLR.reg = (1 << PTP[PTPNbr].Pin); //pull down + PORT->Group[PTP[PTPNbr].Port].DIRCLR.reg = (1 << PTP[PTPNbr].Pin); //Output + PORT->Group[PTP[PTPNbr].Port].OUTCLR.reg = (1 << PTP[PTPNbr].Pin); //pull down return (((PORT->Group[PTP[PTPNbr].Port].IN.reg >> PTP[PTPNbr].Pin)) & 0x01); } /****************************************************************************** @@ -631,17 +703,14 @@ static void LuosHAL_CRCInit(void) ******************************************************************************/ void LuosHAL_ComputeCRC(uint8_t *data, uint8_t *crc) { - for (uint8_t i = 0; i < 1; ++i) + uint16_t dbyte = *data; + *(uint16_t *)crc ^= dbyte << 8; + for (uint8_t j = 0; j < 8; ++j) { - uint16_t dbyte = data[i]; - *(uint16_t *)crc ^= dbyte << 8; - for (uint8_t j = 0; j < 8; ++j) - { - uint16_t mix = *(uint16_t *)crc & 0x8000; - *(uint16_t *)crc = (*(uint16_t *)crc << 1); - if (mix) - *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; - } + uint16_t mix = *(uint16_t *)crc & 0x8000; + *(uint16_t *)crc = (*(uint16_t *)crc << 1); + if (mix) + *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; } } /****************************************************************************** @@ -651,7 +720,7 @@ void LuosHAL_ComputeCRC(uint8_t *data, uint8_t *crc) ******************************************************************************/ static void LuosHAL_FlashInit(void) { - NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY | NVMCTRL_CTRLB_SLEEPPRM_WAKEONACCESS + NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY | NVMCTRL_CTRLB_SLEEPPRM_WAKEONACCESS | NVMCTRL_CTRLB_RWS(1) | NVMCTRL_CTRLB_MANW; } /****************************************************************************** @@ -680,7 +749,7 @@ void LuosHAL_FlashWriteLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *dat { uint32_t i = 0; uint32_t * paddress = (uint32_t *)addr; - + // Before writing we have to erase the entire page // to do that we have to backup current falues by copying it into RAM uint8_t page_backup[16 * PAGE_SIZE]; @@ -714,29 +783,4 @@ void LuosHAL_FlashReadLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *data memcpy(data, (void *)(addr), size); } -/////////////////////////Special LuosHAL function/////////////////////////// -void PINOUT_IRQHANDLER() -{ - uint32_t FlagIT = 0; - for (uint8_t i = 0; i < NBR_PORT; i++) - { - FlagIT = (EIC->INTFLAG.reg & (1 << PTP[i].Irq)); - - if (FlagIT) - { - LuosHAL_GPIOProcess(PTP[i].Pin); - EIC->INTFLAG.reg = (uint32_t)(1 << PTP[i].Irq); - } - } -} -void LUOS_COM_IRQHANDLER() -{ - LuosHAL_ComReceive(); -} - -void LUOS_TIMER_IRQHANDLER() -{ - LuosHAL_ComTimeout(); -} - diff --git a/ATSAMD21_ARDUINO/luos_hal.h b/ATSAMD21_ARDUINO/luos_hal.h index 27c9f43..b5ab318 100644 --- a/ATSAMD21_ARDUINO/luos_hal.h +++ b/ATSAMD21_ARDUINO/luos_hal.h @@ -32,10 +32,10 @@ uint32_t LuosHAL_GetSystick(void); void LuosHAL_ComInit(uint32_t Baudrate); void LuosHAL_SetTxState(uint8_t Enable); void LuosHAL_SetRxState(uint8_t Enable); -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size); -void LuosHAL_SetTxLockDetecState(uint8_t Enable); +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size); uint8_t LuosHAL_GetTxLockState(void); -void LuosHAL_ComTxComplete(void); +void LuosHAL_SetRxDetecPin(uint8_t Enable); +void LuosHAL_ResetTimeout(uint16_t nbrbit); void LuosHAL_SetPTPDefaultState(uint8_t PTPNbr); void LuosHAL_SetPTPReverseState(uint8_t PTPNbr); void LuosHAL_PushPTP(uint8_t PTPNbr); diff --git a/ATSAMD21_ARDUINO/luos_hal_config.h b/ATSAMD21_ARDUINO/luos_hal_config.h index 275584c..93eed99 100644 --- a/ATSAMD21_ARDUINO/luos_hal_config.h +++ b/ATSAMD21_ARDUINO/luos_hal_config.h @@ -13,6 +13,8 @@ #include #include +//If your MCU do not Have DMA for tx transmit define USE_TX_IT + #define DISABLE 0x00 #ifndef MCUFREQ @@ -131,6 +133,25 @@ #ifndef LUOS_COM_IRQHANDLER #define LUOS_COM_IRQHANDLER() SERCOM0_Handler() #endif +/******************************************************************************* + * DMA CONFIG + ******************************************************************************/ +#ifndef LUOS_DMA_CLOCK_ENABLE +#define LUOS_DMA_CLOCK_ENABLE() \ + do \ + { \ + PM->APBCMASK.reg |= PM_AHBMASK_DMAC; \ + } while (0U) +#endif +#ifndef LUOS_DMA +#define LUOS_DMA DMAC +#endif +#ifndef LUOS_DMA_TRIGGER +#define LUOS_DMA_TRIGGER 2 +#endif +#ifndef LUOS_DMA_CHANNEL +#define LUOS_DMA_CHANNEL 0 +#endif /******************************************************************************* * COM TIMEOUT CONFIG ******************************************************************************/ diff --git a/STM32F0/luos_hal.c b/STM32F0/luos_hal.c index 39ee387..3054f50 100644 --- a/STM32F0/luos_hal.c +++ b/STM32F0/luos_hal.c @@ -1,6 +1,6 @@ /****************************************************************************** * @file luosHAL - * @brief Luos Hardware Abstration Layer. Describe Low layer fonction + * @brief Luos Hardware Abstration Layer. Describe Low layer fonction * @MCU Family STM32FO * @author Luos * @version 0.0.0 @@ -15,20 +15,24 @@ //MCU dependencies this HAL is for family STM32FO you can find //the HAL stm32cubef0 on ST web site #include "stm32f0xx_ll_usart.h" +#include "stm32f0xx_ll_gpio.h" +#include "stm32f0xx_ll_tim.h" +#include "stm32f0xx_ll_exti.h" +#include "stm32f0xx_ll_dma.h" +#include "stm32f0xx_ll_system.h" /******************************************************************************* * Definitions ******************************************************************************/ -#define TIMER_RELOAD_CNT 20 +#define DEFAULT_TIMEOUT 20 /******************************************************************************* * Variables ******************************************************************************/ -#ifdef STM32F0xx_HAL_CRC_H +#ifdef USE_CRC_HW CRC_HandleTypeDef hcrc; #endif GPIO_InitTypeDef GPIO_InitStruct = {0}; -TIM_HandleTypeDef TimerHandle = {0}; -uint32_t Timer_Prescaler = (MCUFREQ/DEFAULTBAUDRATE)/TIMERDIV;//(freq MCU/freq timer)/divider timer clock source +uint32_t Timer_Prescaler = (MCUFREQ / DEFAULTBAUDRATE) / TIMERDIV; //(freq MCU/freq timer)/divider timer clock source typedef struct { @@ -38,6 +42,10 @@ typedef struct } Port_t; Port_t PTP[NBR_PORT]; + +volatile uint16_t data_size_to_transmit = 0; +volatile uint8_t *tx_data = 0; + /******************************************************************************* * Function ******************************************************************************/ @@ -45,12 +53,8 @@ static void LuosHAL_SystickInit(void); static void LuosHAL_FlashInit(void); static void LuosHAL_CRCInit(void); static void LuosHAL_TimeoutInit(void); -static void LuosHAL_ResetTimeout(void); -static inline void LuosHAL_ComTimeout(void); static void LuosHAL_GPIOInit(void); static void LuosHAL_FlashEraseLuosMemoryInfo(void); -static inline void LuosHAL_ComReceive(void); -static inline void LuosHAL_GPIOProcess(uint16_t GPIO); static void LuosHAL_RegisterPTP(void); /////////////////////////Luos Library Needed function/////////////////////////// @@ -87,6 +91,7 @@ void LuosHAL_SetIrqState(uint8_t Enable) if (Enable == true) { __enable_irq(); + } else { @@ -141,8 +146,23 @@ void LuosHAL_ComInit(uint32_t Baudrate) HAL_NVIC_SetPriority(LUOS_COM_IRQ, 0, 1); //Timeout Initialization - Timer_Prescaler = (MCUFREQ/Baudrate)/TIMERDIV; + Timer_Prescaler = (MCUFREQ / Baudrate) / TIMERDIV; LuosHAL_TimeoutInit(); + +#ifndef USE_TX_IT + LUOS_DMA_CLOCK_ENABLE(); + + LL_DMA_SetDataTransferDirection(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + LL_DMA_SetChannelPriorityLevel(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_PRIORITY_LOW); + LL_DMA_SetMode(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_MODE_NORMAL); + LL_DMA_SetPeriphIncMode(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetMemoryIncMode(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetPeriphSize(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_PDATAALIGN_BYTE); + LL_DMA_SetMemorySize(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_MDATAALIGN_BYTE); + LL_SYSCFG_SetRemapDMA_USART(LUOS_DMA_REMAP); + LL_DMA_SetPeriphAddress(LUOS_DMA, LUOS_DMA_CHANNEL, (uint32_t)&LUOS_COM->TDR); +#endif + } /****************************************************************************** * @brief Tx enable/disable relative to com @@ -153,19 +173,32 @@ void LuosHAL_SetTxState(uint8_t Enable) { if (Enable == true) { - COM_TX_PORT->OTYPER &= ~(uint32_t)(COM_TX_PIN);//put Tx in push pull - if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(TX_EN_PORT, TX_EN_PIN, GPIO_PIN_SET); - } + // Put Tx in push pull + LL_GPIO_SetPinOutputType(COM_TX_PORT, COM_TX_PIN, LL_GPIO_OUTPUT_PUSHPULL); + if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) + { + LL_GPIO_SetOutputPin(TX_EN_PORT, TX_EN_PIN); + } } else { - COM_TX_PORT->OTYPER |= (uint32_t)(COM_TX_PIN);//put Tx in Open drain - if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(TX_EN_PORT, TX_EN_PIN, GPIO_PIN_RESET); - } + // Put Tx in open drain + LL_GPIO_SetPinOutputType(COM_TX_PORT, COM_TX_PIN, LL_GPIO_OUTPUT_OPENDRAIN); + if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) + { + LL_GPIO_ResetOutputPin(TX_EN_PORT, TX_EN_PIN); + } +#ifdef USE_TX_IT + // Stop current transmit operation + data_size_to_transmit = 0; + // Disable Transmission empty buffer interrupt + LL_USART_DisableIT_TXE(LUOS_COM); +#else + LL_USART_DisableDMAReq_TX(LUOS_COM); + LL_DMA_DisableChannel(LUOS_DMA, LUOS_DMA_CHANNEL); +#endif + // Disable Transmission complete interrupt + LL_USART_DisableIT_TC(LUOS_COM); } } /****************************************************************************** @@ -177,90 +210,134 @@ void LuosHAL_SetRxState(uint8_t Enable) { if (Enable == true) { - LUOS_COM->RQR |= USART_RQR_RXFRQ;//clear data register - LUOS_COM->CR1 |= USART_CR1_RE;// Enable Rx com - LUOS_COM->CR1 |= USART_CR1_RXNEIE;// Enable Rx IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(RX_EN_PORT, RX_EN_PIN, GPIO_PIN_RESET); - } + LL_USART_RequestRxDataFlush(LUOS_COM); // Clear data register + LL_USART_EnableDirectionRx(LUOS_COM); // Enable Rx com + LL_USART_EnableIT_RXNE(LUOS_COM);// Enable Rx IT } else { - LUOS_COM->CR1 &= ~USART_CR1_RE;// disable Rx com - LUOS_COM->CR1 &= ~USART_CR1_RXNEIE;// disable Rx IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(RX_EN_PORT, RX_EN_PIN, GPIO_PIN_SET); - } + LL_USART_DisableDirectionRx(LUOS_COM); // Disable Rx com + LL_USART_DisableIT_RXNE(LUOS_COM); // Disable Rx IT } } /****************************************************************************** - * @brief Process data receive + * @brief Process data send or receive * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComReceive(void) +void LUOS_COM_IRQHANDLER() { - LuosHAL_ResetTimeout(); + // Reset timeout to it's default value + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + + // reception management if ((LL_USART_IsActiveFlag_RXNE(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_RXNE(LUOS_COM) != RESET)) { + // We receive a byte uint8_t data = LL_USART_ReceiveData8(LUOS_COM); ctx.rx.callback(&data); // send reception byte to state machine + if (data_size_to_transmit == 0) + { + LUOS_COM->ICR = 0xFFFFFFFF; + return; + } } else if (LL_USART_IsActiveFlag_FE(LUOS_COM) != RESET) { - LL_USART_ClearFlag_FE(LUOS_COM); + // Framing ERROR ctx.rx.status.rx_framing_error = true; } - else + + // Transmission management + if ((LL_USART_IsActiveFlag_TC(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_TC(LUOS_COM) != RESET)) { - LUOS_COM->ICR = 0xFFFFFFFF; + // Transmission complete + // Switch to reception mode + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); + // Disable transmission complete IRQ + LL_USART_ClearFlag_TC(LUOS_COM); + LL_USART_DisableIT_TC(LUOS_COM); } -} -/****************************************************************************** - * @brief Process data transmit - * @param None - * @return None - ******************************************************************************/ -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size) -{ - for (uint16_t i = 0; i < size; i++) +#ifdef USE_TX_IT + else if ((LL_USART_IsActiveFlag_TXE(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_TXE(LUOS_COM) != RESET)) { - ctx.tx.lock = true; - while (!LL_USART_IsActiveFlag_TXE(LUOS_COM)) - { - } - if (ctx.tx.collision) + // Transmit buffer empty (this is a software DMA) + data_size_to_transmit--; + LL_USART_TransmitData8(LUOS_COM, *(tx_data++)); + if (data_size_to_transmit == 0) { - // There is a collision - ctx.tx.collision = FALSE; - return 1; + // Transmission complete, stop loading data and watch for the end of transmission + // Disable Transmission empty buffer interrupt + LL_USART_DisableIT_TXE(LUOS_COM); + // Enable Transmission complete interrupt + LL_USART_EnableIT_TC(LUOS_COM); } - LL_USART_TransmitData8(LUOS_COM, *(data + i)); - LuosHAL_ResetTimeout(); } - __HAL_TIM_DISABLE_IT(&TimerHandle, TIM_IT_UPDATE); - return 0; +#endif + LUOS_COM->ICR = 0xFFFFFFFF; } /****************************************************************************** - * @brief Luos Tx communication complete + * @brief Process data transmit * @param None * @return None ******************************************************************************/ -void LuosHAL_ComTxComplete(void) +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size) { - while (!LL_USART_IsActiveFlag_TC(LUOS_COM)); - LuosHAL_ResetTimeout(); + while (LL_USART_IsActiveFlag_TXE(LUOS_COM) == RESET) + ; + // Disable RX detec pin if needed + // Enable TX + LuosHAL_SetTxState(true); + + // Reduce size by one because we send one directly + data_size_to_transmit = size - 1; + if (size > 1) + { + // Start the data buffer transmission + // **** NO DMA + //Copy the data pointer globally alowing to keep it and run the transmission. + tx_data = data; +#ifdef USE_TX_IT + // Send the first byte + LL_USART_TransmitData8(LUOS_COM, *(tx_data++)); + // Enable Transmission empty buffer interrupt to transmit next datas + LL_USART_EnableIT_TXE(LUOS_COM); + // Disable Transmission complete interrupt + LL_USART_DisableIT_TC(LUOS_COM); +#else + data_size_to_transmit = 0;//Reset this value avoiding to check IT TC during collision + // Disable DMA to load new length to be tranmitted + LL_DMA_DisableChannel(LUOS_DMA, LUOS_DMA_CHANNEL); + // configure address to be transmitted by DMA + LL_DMA_SetMemoryAddress(LUOS_DMA, LUOS_DMA_CHANNEL, (uint32_t)data); + // set length to be tranmitted + LL_DMA_SetDataLength(LUOS_DMA, LUOS_DMA_CHANNEL, size); + // set request DMA + LL_USART_EnableDMAReq_TX(LUOS_COM); + // Enable DMA again + LL_DMA_EnableChannel(LUOS_DMA, LUOS_DMA_CHANNEL); + // enable transmit complete + LL_USART_EnableIT_TC(LUOS_COM); +#endif + } + else + { + // Transmit the only byte we have + LL_USART_TransmitData8(LUOS_COM, *data); + // Enable Transmission complete interrupt because we only have one. + LL_USART_EnableIT_TC(LUOS_COM); + } + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } /****************************************************************************** * @brief set state of Txlock detection pin * @param None * @return Lock status ******************************************************************************/ -void LuosHAL_SetTxLockDetecState(uint8_t Enable) +void LuosHAL_SetRxDetecPin(uint8_t Enable) { - if (TX_LOCK_DETECT_IRQ != DISABLE) + if (TX_LOCK_DETECT_IRQ != DISABLE) { __HAL_GPIO_EXTI_CLEAR_IT(TX_LOCK_DETECT_IRQ); if (Enable == true) @@ -269,7 +346,7 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) } else { - EXTI->IMR &= ~ TX_LOCK_DETECT_PIN; + EXTI->IMR &= ~TX_LOCK_DETECT_PIN; } } } @@ -281,26 +358,29 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) uint8_t LuosHAL_GetTxLockState(void) { uint8_t result = false; - - #ifdef USART_ISR_BUSY - if (READ_BIT(LUOS_COM->ISR, USART_ISR_BUSY) == (USART_ISR_BUSY)) + +#ifdef USART_ISR_BUSY + if (LL_USART_IsActiveFlag_BUSY(LUOS_COM) == true) { - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); result = true; } - #else +#else if ((TX_LOCK_DETECT_PIN != DISABLE) && (TX_LOCK_DETECT_PORT != DISABLE)) { - if(TX_LOCK_DETECT_IRQ == DISABLE) + if(HAL_GPIO_ReadPin(TX_LOCK_DETECT_PORT, TX_LOCK_DETECT_PIN) == GPIO_PIN_RESET) { - result = HAL_GPIO_ReadPin(TX_LOCK_DETECT_PORT, TX_LOCK_DETECT_PIN); - if(result == true) + result = true; + } + if (TX_LOCK_DETECT_IRQ == DISABLE) + { + if (result == true) { - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } } } - #endif +#endif return result; } /****************************************************************************** @@ -310,51 +390,55 @@ uint8_t LuosHAL_GetTxLockState(void) ******************************************************************************/ static void LuosHAL_TimeoutInit(void) { + LL_TIM_InitTypeDef TimerInit = {0}; + //initialize clock LUOS_TIMER_CLOCK_ENABLE(); - TimerHandle.Instance = LUOS_TIMER; - TimerHandle.Init.Period = TIMER_RELOAD_CNT; - TimerHandle.Init.Prescaler = Timer_Prescaler-1; - TimerHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - TimerHandle.Init.CounterMode = TIM_COUNTERMODE_UP; - TimerHandle.Init.RepetitionCounter = 0; - TimerHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - if(HAL_TIM_Base_Init(&TimerHandle) != HAL_OK) - { - while(1); - } + TimerInit.Autoreload = DEFAULT_TIMEOUT; + TimerInit.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TimerInit.CounterMode = LL_TIM_COUNTERMODE_UP; + TimerInit.Prescaler = Timer_Prescaler - 1; + TimerInit.RepetitionCounter = 0; + while (LL_TIM_Init(LUOS_TIMER, &TimerInit) != SUCCESS) + ; + LL_TIM_EnableIT_UPDATE(LUOS_TIMER); HAL_NVIC_SetPriority(LUOS_TIMER_IRQ, 0, 2); HAL_NVIC_EnableIRQ(LUOS_TIMER_IRQ); } /****************************************************************************** - * @brief Luos Timeout for Rx communication + * @brief Luos Timeout communication * @param None * @return None ******************************************************************************/ -static void LuosHAL_ResetTimeout(void) +void LuosHAL_ResetTimeout(uint16_t nbrbit) { - LUOS_TIMER->CR1 &= ~(TIM_CR1_CEN);//disable counter - NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// clear IT pending - __HAL_TIM_CLEAR_IT(&TimerHandle, TIM_IT_UPDATE);// clear IT flag - LUOS_TIMER->CNT = 0;//reset counter - LUOS_TIMER->ARR = TIMER_RELOAD_CNT;//relaod value - __HAL_TIM_ENABLE_IT(&TimerHandle, TIM_IT_UPDATE); - LUOS_TIMER->CR1 |= TIM_CR1_CEN;//enable counter + LL_TIM_DisableCounter(LUOS_TIMER); + NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// Clear IT pending NVIC + LL_TIM_ClearFlag_UPDATE(LUOS_TIMER); + LL_TIM_SetCounter(LUOS_TIMER, 0);// Reset counter + if(nbrbit != 0) + { + LL_TIM_SetAutoReload(LUOS_TIMER, nbrbit);//reload value + LL_TIM_EnableCounter(LUOS_TIMER); + } } /****************************************************************************** - * @brief Luos Timeout for Rx communication + * @brief Luos Timeout communication * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComTimeout(void) +void LUOS_TIMER_IRQHANDLER() { - if (__HAL_TIM_GET_FLAG(&TimerHandle, TIM_FLAG_UPDATE) != RESET) + if (LL_TIM_IsActiveFlag_UPDATE(LUOS_TIMER) != RESET) { - __HAL_TIM_CLEAR_IT(&TimerHandle, TIM_IT_UPDATE); - LUOS_TIMER->CR1 &= ~(TIM_CR1_CEN); - if (ctx.tx.lock == true) + LL_TIM_ClearFlag_UPDATE(LUOS_TIMER); + LL_TIM_DisableCounter(LUOS_TIMER); + if ((ctx.tx.lock == true)&&(LuosHAL_GetTxLockState() == false)) { + // Enable RX detection pin if needed + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); Recep_Timeout(); } } @@ -371,36 +455,22 @@ static void LuosHAL_GPIOInit(void) if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : RxEN_Pin */ - GPIO_InitStruct.Pin = RX_EN_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(RX_EN_PORT, &GPIO_InitStruct); + /*Configure GPIO pins : RxEN_Pin */ + GPIO_InitStruct.Pin = RX_EN_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(RX_EN_PORT, &GPIO_InitStruct); } if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : TxEN_Pin */ - GPIO_InitStruct.Pin = TX_EN_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(TX_EN_PORT, &GPIO_InitStruct); - } - - /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ - GPIO_InitStruct.Pin = TX_LOCK_DETECT_PIN; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) - { - if (TX_LOCK_DETECT_IRQ != DISABLE) - { - GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; - } - HAL_GPIO_Init(TX_LOCK_DETECT_PORT, &GPIO_InitStruct); + /*Configure GPIO pins : TxEN_Pin */ + GPIO_InitStruct.Pin = TX_EN_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(TX_EN_PORT, &GPIO_InitStruct); } /*Configure GPIO pin : TxPin */ @@ -435,11 +505,20 @@ static void LuosHAL_GPIOInit(void) HAL_NVIC_EnableIRQ(PTP[i].IRQ); } - if (TX_LOCK_DETECT_IRQ != DISABLE) + if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) { - EXTI->IMR &= ~ TX_LOCK_DETECT_PIN; - HAL_NVIC_SetPriority(TX_LOCK_DETECT_IRQ, 1, 0); - HAL_NVIC_EnableIRQ(TX_LOCK_DETECT_IRQ); + /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ + GPIO_InitStruct.Pin = TX_LOCK_DETECT_PIN; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + if (TX_LOCK_DETECT_IRQ != DISABLE) + { + GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; + HAL_NVIC_SetPriority(TX_LOCK_DETECT_IRQ, 1, 0); + HAL_NVIC_EnableIRQ(TX_LOCK_DETECT_IRQ); + } + HAL_GPIO_Init(TX_LOCK_DETECT_PORT, &GPIO_InitStruct); } } /****************************************************************************** @@ -478,20 +557,20 @@ static void LuosHAL_RegisterPTP(void) * @param GPIO IT line * @return None ******************************************************************************/ -static inline void LuosHAL_GPIOProcess(uint16_t GPIO) +void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) { ////Process for Tx Lock Detec - if (GPIO == TX_LOCK_DETECT_PIN) + if ((GPIO_Pin == TX_LOCK_DETECT_PIN)&&(TX_LOCK_DETECT_IRQ != DISABLE)) { - ctx.tx.lock = true; - LuosHAL_ResetTimeout(); - EXTI->IMR &= ~ TX_LOCK_DETECT_PIN; + ctx.tx.lock = true; + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + EXTI->IMR &= ~TX_LOCK_DETECT_PIN; } else { for (uint8_t i = 0; i < NBR_PORT; i++) { - if (GPIO == PTP[i].Pin) + if (GPIO_Pin == PTP[i].Pin) { PortMng_PtpHandler(i); break; @@ -558,7 +637,7 @@ uint8_t LuosHAL_GetPTPState(uint8_t PTPNbr) ******************************************************************************/ static void LuosHAL_CRCInit(void) { -#ifdef STM32F0xx_HAL_CRC_H +#ifdef USE_CRC_HW __HAL_RCC_CRC_CLK_ENABLE(); hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; @@ -582,24 +661,19 @@ static void LuosHAL_CRCInit(void) ******************************************************************************/ void LuosHAL_ComputeCRC(uint8_t *data, uint8_t *crc) { -#ifdef STM32F0xx_HAL_CRC_H - LuosHAL_SetIrqState(false); +#ifdef USE_CRC_HW hcrc.Instance->INIT = *(uint16_t *)crc; __HAL_CRC_DR_RESET(&hcrc); *(uint16_t *)crc = (uint16_t)HAL_CRC_Accumulate(&hcrc, (uint32_t *)data, 1); - LuosHAL_SetIrqState(true); #else - for (uint8_t i = 0; i < 1; ++i) + uint16_t dbyte = *data; + *(uint16_t *)crc ^= dbyte << 8; + for (uint8_t j = 0; j < 8; ++j) { - uint16_t dbyte = data[i]; - *(uint16_t *)crc ^= dbyte << 8; - for (uint8_t j = 0; j < 8; ++j) - { - uint16_t mix = *(uint16_t *)crc & 0x8000; - *(uint16_t *)crc = (*(uint16_t *)crc << 1); - if (mix) - *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; - } + uint16_t mix = *(uint16_t *)crc & 0x8000; + *(uint16_t *)crc = (*(uint16_t *)crc << 1); + if (mix) + *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; } #endif } @@ -670,16 +744,3 @@ void LuosHAL_FlashReadLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *data memcpy(data, (void *)(addr), size); } -/////////////////////////Special LuosHAL function/////////////////////////// -void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) -{ - LuosHAL_GPIOProcess(GPIO_Pin); -} -void LUOS_COM_IRQHANDLER() -{ - LuosHAL_ComReceive(); -} -void LUOS_TIMER_IRQHANDLER() -{ - LuosHAL_ComTimeout(); -} diff --git a/STM32F0/luos_hal.h b/STM32F0/luos_hal.h index dcd2444..bbe8a99 100644 --- a/STM32F0/luos_hal.h +++ b/STM32F0/luos_hal.h @@ -31,10 +31,10 @@ uint32_t LuosHAL_GetSystick(void); void LuosHAL_ComInit(uint32_t Baudrate); void LuosHAL_SetTxState(uint8_t Enable); void LuosHAL_SetRxState(uint8_t Enable); -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size); -void LuosHAL_SetTxLockDetecState(uint8_t Enable); +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size); uint8_t LuosHAL_GetTxLockState(void); -void LuosHAL_ComTxComplete(void); +void LuosHAL_ResetTimeout(uint16_t nbrbit); +void LuosHAL_SetRxDetecPin(uint8_t Enable); void LuosHAL_SetPTPDefaultState(uint8_t PTPNbr); void LuosHAL_SetPTPReverseState(uint8_t PTPNbr); void LuosHAL_PushPTP(uint8_t PTPNbr); @@ -42,5 +42,4 @@ uint8_t LuosHAL_GetPTPState(uint8_t PTPNbr); void LuosHAL_ComputeCRC(uint8_t *data, uint8_t *crc); void LuosHAL_FlashWriteLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *data); void LuosHAL_FlashReadLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *data); - #endif /* _LUOSHAL_H_ */ diff --git a/STM32F0/luos_hal_config.h b/STM32F0/luos_hal_config.h index 7565912..8646438 100644 --- a/STM32F0/luos_hal_config.h +++ b/STM32F0/luos_hal_config.h @@ -12,6 +12,9 @@ #include "stm32f0xx_hal.h" +//If your MCU do not Have DMA for tx transmit define USE_TX_IT +#define USE_CRC_HW + #define DISABLE 0x00 #ifndef MCUFREQ @@ -115,6 +118,21 @@ #ifndef LUOS_COM_IRQHANDLER #define LUOS_COM_IRQHANDLER() USART1_IRQHandler() #endif +/******************************************************************************* + * FLASH CONFIG + ******************************************************************************/ +#ifndef LUOS_DMA_CLOCK_ENABLE +#define LUOS_DMA_CLOCK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE(); +#endif +#ifndef LUOS_DMA +#define LUOS_DMA DMA1 +#endif +#ifndef LUOS_DMA_CHANNEL +#define LUOS_DMA_CHANNEL LL_DMA_CHANNEL_2 +#endif +#ifndef LUOS_DMA_REMAP +#define LUOS_DMA_REMAP 0 +#endif /******************************************************************************* * COM TIMEOUT CONFIG ******************************************************************************/ diff --git a/STM32F4/luos_hal.c b/STM32F4/luos_hal.c index 43f4ffb..141b2e6 100644 --- a/STM32F4/luos_hal.c +++ b/STM32F4/luos_hal.c @@ -15,20 +15,24 @@ //MCU dependencies this HAL is for family STM32F4 you can find //the HAL stm32cubeF4 on ST web site #include "stm32f4xx_ll_usart.h" +#include "stm32f4xx_ll_gpio.h" +#include "stm32f4xx_ll_tim.h" +#include "stm32f4xx_ll_exti.h" +#include "stm32f4xx_ll_dma.h" +#include "stm32f4xx_ll_system.h" /******************************************************************************* * Definitions ******************************************************************************/ -#define TIMER_RELOAD_CNT 20 - +#define DEFAULT_TIMEOUT 20 /******************************************************************************* * Variables ******************************************************************************/ -#ifdef STM32F4xx_HAL_CRC_H +#ifdef USE_CRC_HW CRC_HandleTypeDef hcrc; #endif GPIO_InitTypeDef GPIO_InitStruct = {0}; -TIM_HandleTypeDef TimerHandle = {0}; -uint32_t Timer_Prescaler = (MCUFREQ/DEFAULTBAUDRATE)/TIMERDIV;//(freq MCU/freq timer)/divider timer clock source + +uint32_t Timer_Prescaler = (MCUFREQ / DEFAULTBAUDRATE) / TIMERDIV; //(freq MCU/freq timer)/divider timer clock source typedef struct { @@ -38,6 +42,9 @@ typedef struct } Port_t; Port_t PTP[NBR_PORT]; + +volatile uint16_t data_size_to_transmit = 0; +volatile uint8_t *tx_data = 0; /******************************************************************************* * Function ******************************************************************************/ @@ -45,12 +52,8 @@ static void LuosHAL_SystickInit(void); static void LuosHAL_FlashInit(void); static void LuosHAL_CRCInit(void); static void LuosHAL_TimeoutInit(void); -static void LuosHAL_ResetTimeout(void); -static inline void LuosHAL_ComTimeout(void); static void LuosHAL_GPIOInit(void); static void LuosHAL_FlashEraseLuosMemoryInfo(void); -static inline void LuosHAL_ComReceive(void); -static inline void LuosHAL_GPIOProcess(uint16_t GPIO); static void LuosHAL_RegisterPTP(void); /////////////////////////Luos Library Needed function/////////////////////////// @@ -121,7 +124,7 @@ void LuosHAL_ComInit(uint32_t Baudrate) LL_USART_InitTypeDef USART_InitStruct; - // Initialise USART3 + // Initialise USART LL_USART_Disable(LUOS_COM); USART_InitStruct.BaudRate = Baudrate; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; @@ -141,8 +144,23 @@ void LuosHAL_ComInit(uint32_t Baudrate) HAL_NVIC_SetPriority(LUOS_COM_IRQ, 0, 1); //Timeout Initialization - Timer_Prescaler = (MCUFREQ/Baudrate)/TIMERDIV; + Timer_Prescaler = (MCUFREQ / Baudrate) / TIMERDIV; LuosHAL_TimeoutInit(); + +#ifndef USE_TX_IT + LUOS_DMA_CLOCK_ENABLE(); + + LL_DMA_SetChannelSelection(LUOS_DMA, LUOS_DMA_STREAM, LUOS_DMA_CHANNEL); + LL_DMA_SetDataTransferDirection(LUOS_DMA, LUOS_DMA_STREAM, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + LL_DMA_SetStreamPriorityLevel(LUOS_DMA, LUOS_DMA_STREAM, LL_DMA_PRIORITY_LOW); + LL_DMA_SetMode(LUOS_DMA, LUOS_DMA_STREAM, LL_DMA_MODE_NORMAL); + LL_DMA_SetPeriphIncMode(LUOS_DMA, LUOS_DMA_STREAM, LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetMemoryIncMode(LUOS_DMA, LUOS_DMA_STREAM, LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetPeriphSize(LUOS_DMA, LUOS_DMA_STREAM, LL_DMA_PDATAALIGN_BYTE); + LL_DMA_SetMemorySize(LUOS_DMA, LUOS_DMA_STREAM, LL_DMA_MDATAALIGN_BYTE); + LL_DMA_DisableFifoMode(LUOS_DMA, LUOS_DMA_STREAM); + LL_DMA_SetPeriphAddress(LUOS_DMA, LUOS_DMA_STREAM, (uint32_t)&LUOS_COM->DR); +#endif } /****************************************************************************** * @brief Tx enable/disable relative to com @@ -153,19 +171,32 @@ void LuosHAL_SetTxState(uint8_t Enable) { if (Enable == true) { - COM_TX_PORT->OTYPER &= ~(uint32_t)(COM_TX_PIN);//put Tx in push pull - if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(TX_EN_PORT, TX_EN_PIN, GPIO_PIN_SET); - } + // Put Tx in push pull + LL_GPIO_SetPinOutputType(COM_TX_PORT, COM_TX_PIN, LL_GPIO_OUTPUT_PUSHPULL); + if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) + { + LL_GPIO_SetOutputPin(TX_EN_PORT, TX_EN_PIN); + } } else { - COM_TX_PORT->OTYPER |= (uint32_t)(COM_TX_PIN);//put Tx in Open drain - if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(TX_EN_PORT, TX_EN_PIN, GPIO_PIN_RESET); - } + // Put Tx in open drain + LL_GPIO_SetPinOutputType(COM_TX_PORT, COM_TX_PIN, LL_GPIO_OUTPUT_OPENDRAIN); + if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) + { + LL_GPIO_ResetOutputPin(TX_EN_PORT, TX_EN_PIN); + } +#ifdef USE_TX_IT + // Stop current transmit operation + data_size_to_transmit = 0; + // Disable Transmission empty buffer interrupt + LL_USART_DisableIT_TXE(LUOS_COM); +#else + LL_USART_DisableDMAReq_TX(LUOS_COM); + LL_DMA_DisableStream(LUOS_DMA, LUOS_DMA_STREAM); +#endif + // Disable Transmission complete interrupt + LL_USART_DisableIT_TC(LUOS_COM); } } /****************************************************************************** @@ -178,21 +209,13 @@ void LuosHAL_SetRxState(uint8_t Enable) if (Enable == true) { LL_USART_ReceiveData8(LUOS_COM);//empty buffer - LUOS_COM->CR1 |= USART_CR1_RE;// Enable RX - LUOS_COM->CR1 |= USART_CR1_RXNEIE;//Enable RX IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(RX_EN_PORT, RX_EN_PIN, GPIO_PIN_RESET); - } + LL_USART_EnableDirectionRx(LUOS_COM); // Enable Rx com + LL_USART_EnableIT_RXNE(LUOS_COM); // Enable Rx IT } else { - LUOS_COM->CR1 &= ~USART_CR1_RE;// Disable RX - LUOS_COM->CR1 &= ~USART_CR1_RXNEIE;// Disable RX IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(RX_EN_PORT, RX_EN_PIN, GPIO_PIN_SET); - } + LL_USART_DisableDirectionRx(LUOS_COM); // Disable Rx com + LL_USART_DisableIT_RXNE(LUOS_COM); // Disable Rx IT } } /****************************************************************************** @@ -200,66 +223,119 @@ void LuosHAL_SetRxState(uint8_t Enable) * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComReceive(void) +void LUOS_COM_IRQHANDLER() { - LuosHAL_ResetTimeout(); - + // Reset timeout to it's default value + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + // reception management if ((LL_USART_IsActiveFlag_RXNE(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_RXNE(LUOS_COM) != RESET)) { + // We receive a byte uint8_t data = LL_USART_ReceiveData8(LUOS_COM); ctx.rx.callback(&data); // send reception byte to state machine + if (data_size_to_transmit == 0) + { + LUOS_COM->SR = 0xFFFFFFFF; + return; + } } else if (LL_USART_IsActiveFlag_FE(LUOS_COM) != RESET) { - LL_USART_ClearFlag_FE(LUOS_COM); + // Framing ERROR ctx.rx.status.rx_framing_error = true; } - else + + // Transmission management + if ((LL_USART_IsActiveFlag_TC(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_TC(LUOS_COM) != RESET)) { - LUOS_COM->SR = 0xFFFFFFFF; + // Transmission complete + // Switch to reception mode + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); + // Disable transmission complete IRQ + LL_USART_ClearFlag_TC(LUOS_COM); + LL_USART_DisableIT_TC(LUOS_COM); } -} -/****************************************************************************** - * @brief Process data transmit - * @param None - * @return None - ******************************************************************************/ -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size) -{ - for (uint16_t i = 0; i < size; i++) +#ifdef USE_TX_IT + else if ((LL_USART_IsActiveFlag_TXE(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_TXE(LUOS_COM) != RESET)) { - ctx.tx.lock = true; - while (!LL_USART_IsActiveFlag_TXE(LUOS_COM)) + // Transmit buffer empty (this is a software DMA) + data_size_to_transmit--; + LL_USART_TransmitData8(LUOS_COM, *(tx_data++)); + if (data_size_to_transmit == 0) { + // Transmission complete, stop loading data and watch for the end of transmission + // Disable Transmission empty buffer interrupt + LL_USART_DisableIT_TXE(LUOS_COM); + // Enable Transmission complete interrupt + LL_USART_EnableIT_TC(LUOS_COM); } - if (ctx.tx.collision) - { - // There is a collision - ctx.tx.collision = FALSE; - return 1; - } - LL_USART_TransmitData8(LUOS_COM, *(data + i)); - LuosHAL_ResetTimeout(); } - __HAL_TIM_DISABLE_IT(&TimerHandle, TIM_IT_UPDATE); - return 0; +#endif + LUOS_COM->SR = 0xFFFFFFFF; } /****************************************************************************** - * @brief Luos Tx communication complete + * @brief Process data transmit * @param None * @return None ******************************************************************************/ -void LuosHAL_ComTxComplete(void) +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size) { - while (!LL_USART_IsActiveFlag_TC(LUOS_COM)); - LuosHAL_ResetTimeout(); + while (LL_USART_IsActiveFlag_TXE(LUOS_COM) == RESET) + ; + // Disable RX detec pin if needed + // Enable TX + LuosHAL_SetTxState(true); + + // Reduce size by one because we send one directly + data_size_to_transmit = size - 1; + if (size > 1) + { + // Start the data buffer transmission + // **** NO DMA + //Copy the data pointer globally alowing to keep it and run the transmission. + tx_data = data; +#ifdef USE_TX_IT + // Send the first byte + LL_USART_TransmitData8(LUOS_COM, *(tx_data++)); + // Enable Transmission empty buffer interrupt to transmit next datas + LL_USART_EnableIT_TXE(LUOS_COM); + // Disable Transmission complete interrupt + LL_USART_DisableIT_TC(LUOS_COM); +#else + data_size_to_transmit = 0;//to not check IT TC during collision + // Disable DMA to load new length to be tranmitted + LL_DMA_DisableStream(LUOS_DMA, LUOS_DMA_STREAM); + // configure address to be transmitted by DMA + LL_DMA_SetMemoryAddress(LUOS_DMA, LUOS_DMA_STREAM, (uint32_t)data); + // set length to be tranmitted + LL_DMA_SetDataLength(LUOS_DMA, LUOS_DMA_STREAM, size); + // set request DMA + LL_USART_EnableDMAReq_TX(LUOS_COM); + //clear flag shity way must be change + LUOS_DMA->HIFCR = 0xFFFFFFFF; + LUOS_DMA->LIFCR = 0xFFFFFFFF; + // Enable DMA again + LL_DMA_EnableStream(LUOS_DMA, LUOS_DMA_STREAM); + // enable transmit complete + LL_USART_EnableIT_TC(LUOS_COM); +#endif + } + else + { + // Transmit the only byte we have + LL_USART_TransmitData8(LUOS_COM, *data); + // Enable Transmission complete interrupt because we only have one. + LL_USART_EnableIT_TC(LUOS_COM); + } + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } /****************************************************************************** * @brief set state of Txlock detection pin * @param None * @return Lock status ******************************************************************************/ -void LuosHAL_SetTxLockDetecState(uint8_t Enable) +void LuosHAL_SetRxDetecPin(uint8_t Enable) { if (TX_LOCK_DETECT_IRQ != DISABLE) { @@ -270,7 +346,7 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) } else { - EXTI->IMR &= ~ TX_LOCK_DETECT_PIN; + EXTI->IMR &= ~TX_LOCK_DETECT_PIN; } } } @@ -282,26 +358,29 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) uint8_t LuosHAL_GetTxLockState(void) { uint8_t result = false; - - #ifdef USART_ISR_BUSY - if (READ_BIT(LUOS_COM->ISR, USART_ISR_BUSY) == (USART_ISR_BUSY)) + +#ifdef USART_ISR_BUSY + if (LL_USART_IsActiveFlag_BUSY(LUOS_COM) == true) { - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); result = true; } - #else +#else if ((TX_LOCK_DETECT_PIN != DISABLE) && (TX_LOCK_DETECT_PORT != DISABLE)) { - if(TX_LOCK_DETECT_IRQ == DISABLE) + if(HAL_GPIO_ReadPin(TX_LOCK_DETECT_PORT, TX_LOCK_DETECT_PIN) == GPIO_PIN_RESET) { - result = HAL_GPIO_ReadPin(TX_LOCK_DETECT_PORT, TX_LOCK_DETECT_PIN); - if(result == true) + result = true; + } + if (TX_LOCK_DETECT_IRQ == DISABLE) + { + if (result == true) { - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } } } - #endif +#endif return result; } /****************************************************************************** @@ -311,23 +390,19 @@ uint8_t LuosHAL_GetTxLockState(void) ******************************************************************************/ static void LuosHAL_TimeoutInit(void) { + LL_TIM_InitTypeDef TimerInit = {0}; + //initialize clock LUOS_TIMER_CLOCK_ENABLE(); - //Disable CNT - LUOS_TIMER->CR1 &= ~(TIM_CR1_CEN);//disable counter - - TimerHandle.Instance = LUOS_TIMER; - TimerHandle.Init.Period = TIMER_RELOAD_CNT; - TimerHandle.Init.Prescaler = Timer_Prescaler-1; - TimerHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - TimerHandle.Init.CounterMode = TIM_COUNTERMODE_UP; - TimerHandle.Init.RepetitionCounter = 0; - TimerHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - if(HAL_TIM_Base_Init(&TimerHandle) != HAL_OK) - { - while(1); - } + TimerInit.Autoreload = DEFAULT_TIMEOUT; + TimerInit.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TimerInit.CounterMode = LL_TIM_COUNTERMODE_UP; + TimerInit.Prescaler = Timer_Prescaler - 1; + TimerInit.RepetitionCounter = 0; + while (LL_TIM_Init(LUOS_TIMER, &TimerInit) != SUCCESS) + ; + LL_TIM_EnableIT_UPDATE(LUOS_TIMER); HAL_NVIC_SetPriority(LUOS_TIMER_IRQ, 0, 2); HAL_NVIC_EnableIRQ(LUOS_TIMER_IRQ); } @@ -336,29 +411,34 @@ static void LuosHAL_TimeoutInit(void) * @param None * @return None ******************************************************************************/ -static void LuosHAL_ResetTimeout(void) +void LuosHAL_ResetTimeout(uint16_t nbrbit) { - LUOS_TIMER->CR1 &= ~(TIM_CR1_CEN);//disable counter - NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// clear IT pending - __HAL_TIM_CLEAR_IT(&TimerHandle, TIM_IT_UPDATE);// clear IT flag - LUOS_TIMER->CNT = 0;//reset counter - LUOS_TIMER->ARR = TIMER_RELOAD_CNT;//relaod value - __HAL_TIM_ENABLE_IT(&TimerHandle, TIM_IT_UPDATE); - LUOS_TIMER->CR1 |= TIM_CR1_CEN;//enable counter + LL_TIM_DisableCounter(LUOS_TIMER); + NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// Clear IT pending NVIC + LL_TIM_ClearFlag_UPDATE(LUOS_TIMER); + LL_TIM_SetCounter(LUOS_TIMER, 0);// Reset counter + if(nbrbit != 0) + { + LL_TIM_SetAutoReload(LUOS_TIMER, nbrbit);//reload value + LL_TIM_EnableCounter(LUOS_TIMER); + } } /****************************************************************************** - * @brief Luos Timeout for Rx communication + * @brief Luos communication Timeout * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComTimeout(void) +void LUOS_TIMER_IRQHANDLER() { - if (__HAL_TIM_GET_FLAG(&TimerHandle, TIM_FLAG_UPDATE) != RESET) + if (LL_TIM_IsActiveFlag_UPDATE(LUOS_TIMER) != RESET) { - __HAL_TIM_CLEAR_IT(&TimerHandle, TIM_IT_UPDATE); - LUOS_TIMER->CR1 &= ~(TIM_CR1_CEN); - if (ctx.tx.lock == true) + LL_TIM_ClearFlag_UPDATE(LUOS_TIMER); + LL_TIM_DisableCounter(LUOS_TIMER); + if ((ctx.tx.lock == true)&&(LuosHAL_GetTxLockState() == false)) { + // Enable RX detection pin if needed + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); Recep_Timeout(); } } @@ -373,38 +453,24 @@ static void LuosHAL_GPIOInit(void) //Activate Clock for PIN choosen in luosHAL PORT_CLOCK_ENABLE(); - /*Configure GPIO pins : RxEN_Pin */ if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) { - GPIO_InitStruct.Pin = RX_EN_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(RX_EN_PORT, &GPIO_InitStruct); - } - - /*Configure GPIO pins : TxEN_Pin */ + /*Configure GPIO pins : RxEN_Pin */ + GPIO_InitStruct.Pin = RX_EN_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(RX_EN_PORT, &GPIO_InitStruct); + } + if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) { - GPIO_InitStruct.Pin = TX_EN_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(TX_EN_PORT, &GPIO_InitStruct); - } - - /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ - GPIO_InitStruct.Pin = TX_LOCK_DETECT_PIN; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) - { - if (TX_LOCK_DETECT_IRQ != DISABLE) - { - GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; - } - HAL_GPIO_Init(TX_LOCK_DETECT_PORT, &GPIO_InitStruct); + /*Configure GPIO pins : TxEN_Pin */ + GPIO_InitStruct.Pin = TX_EN_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(TX_EN_PORT, &GPIO_InitStruct); } /*Configure GPIO pin : TxPin */ @@ -439,11 +505,20 @@ static void LuosHAL_GPIOInit(void) HAL_NVIC_EnableIRQ(PTP[i].IRQ); } - if (TX_LOCK_DETECT_IRQ != DISABLE) + if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) { - EXTI->IMR &= ~ TX_LOCK_DETECT_PIN; - HAL_NVIC_SetPriority(TX_LOCK_DETECT_IRQ, 1, 0); - HAL_NVIC_EnableIRQ(TX_LOCK_DETECT_IRQ); + /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ + GPIO_InitStruct.Pin = TX_LOCK_DETECT_PIN; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + if (TX_LOCK_DETECT_IRQ != DISABLE) + { + GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; + HAL_NVIC_SetPriority(TX_LOCK_DETECT_IRQ, 1, 0); + HAL_NVIC_EnableIRQ(TX_LOCK_DETECT_IRQ); + } + HAL_GPIO_Init(TX_LOCK_DETECT_PORT, &GPIO_InitStruct); } } /****************************************************************************** @@ -482,20 +557,20 @@ static void LuosHAL_RegisterPTP(void) * @param GPIO IT line * @return None ******************************************************************************/ -static inline void LuosHAL_GPIOProcess(uint16_t GPIO) +void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) { ////Process for Tx Lock Detec - if (GPIO == TX_LOCK_DETECT_PIN) + if ((GPIO_Pin == TX_LOCK_DETECT_PIN)&&(TX_LOCK_DETECT_IRQ != DISABLE)) { ctx.tx.lock = true; - EXTI->IMR &= ~ TX_LOCK_DETECT_PIN; - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + EXTI->IMR &= ~TX_LOCK_DETECT_PIN; } else { for (uint8_t i = 0; i < NBR_PORT; i++) { - if (GPIO == PTP[i].Pin) + if (GPIO_Pin == PTP[i].Pin) { PortMng_PtpHandler(i); break; @@ -562,7 +637,7 @@ uint8_t LuosHAL_GetPTPState(uint8_t PTPNbr) ******************************************************************************/ static void LuosHAL_CRCInit(void) { -#ifdef STM32L4xx_HAL_CRC_H +#ifdef USE_CRC_HW __HAL_RCC_CRC_CLK_ENABLE(); hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; @@ -586,24 +661,19 @@ static void LuosHAL_CRCInit(void) ******************************************************************************/ void LuosHAL_ComputeCRC(uint8_t *data, uint8_t *crc) { -#ifdef STM32L4xx_HAL_CRC_H - LuosHAL_SetIrqState(false); +#ifdef USE_CRC_HW hcrc.Instance->INIT = *(uint16_t *)crc; __HAL_CRC_DR_RESET(&hcrc); *(uint16_t *)crc = (uint16_t)HAL_CRC_Accumulate(&hcrc, (uint32_t *)data, 1); - LuosHAL_SetIrqState(true); #else - for (uint8_t i = 0; i < 1; ++i) + uint16_t dbyte = *data; + *(uint16_t *)crc ^= dbyte << 8; + for (uint8_t j = 0; j < 8; ++j) { - uint16_t dbyte = data[i]; - *(uint16_t *)crc ^= dbyte << 8; - for (uint8_t j = 0; j < 8; ++j) - { - uint16_t mix = *(uint16_t *)crc & 0x8000; - *(uint16_t *)crc = (*(uint16_t *)crc << 1); - if (mix) - *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; - } + uint16_t mix = *(uint16_t *)crc & 0x8000; + *(uint16_t *)crc = (*(uint16_t *)crc << 1); + if (mix) + *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; } #endif } @@ -674,17 +744,3 @@ void LuosHAL_FlashReadLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *data memcpy(data, (void *)(addr), size); } -/////////////////////////Special LuosHAL function/////////////////////////// -void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) -{ - LuosHAL_GPIOProcess(GPIO_Pin); -} -void LUOS_COM_IRQHANDLER() -{ - LuosHAL_ComReceive(); -} -void LUOS_TIMER_IRQHANDLER() -{ - LuosHAL_ComTimeout(); -} - diff --git a/STM32F4/luos_hal.h b/STM32F4/luos_hal.h index 2dbc01a..3911cf3 100644 --- a/STM32F4/luos_hal.h +++ b/STM32F4/luos_hal.h @@ -18,7 +18,6 @@ #define ADDRESS_ALIASES_FLASH ADDRESS_LAST_PAGE_FLASH #define ADDRESS_BOOT_FLAG_FLASH (ADDRESS_LAST_PAGE_FLASH + PAGE_SIZE) - 4 - /******************************************************************************* * Variables ******************************************************************************/ @@ -32,10 +31,10 @@ uint32_t LuosHAL_GetSystick(void); void LuosHAL_ComInit(uint32_t Baudrate); void LuosHAL_SetTxState(uint8_t Enable); void LuosHAL_SetRxState(uint8_t Enable); -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size); -void LuosHAL_SetTxLockDetecState(uint8_t Enable); +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size); uint8_t LuosHAL_GetTxLockState(void); -void LuosHAL_ComTxComplete(void); +void LuosHAL_SetRxDetecPin(uint8_t Enable); +void LuosHAL_ResetTimeout(uint16_t nbrbit); void LuosHAL_SetPTPDefaultState(uint8_t PTPNbr); void LuosHAL_SetPTPReverseState(uint8_t PTPNbr); void LuosHAL_PushPTP(uint8_t PTPNbr); diff --git a/STM32F4/luos_hal_config.h b/STM32F4/luos_hal_config.h index 81c3621..24a820c 100644 --- a/STM32F4/luos_hal_config.h +++ b/STM32F4/luos_hal_config.h @@ -12,6 +12,9 @@ #include "stm32f4xx_hal.h" +//If your MCU do not Have DMA for tx transmit define USE_TX_IT +//If your MCU have CRC polynome 16 #define USE_CRC_HW + #define DISABLE 0x00 #ifndef MCUFREQ @@ -118,6 +121,24 @@ #ifndef LUOS_COM_IRQHANDLER #define LUOS_COM_IRQHANDLER() USART1_IRQHandler() #endif +/******************************************************************************* + * FLASH CONFIG + ******************************************************************************/ +#ifndef LUOS_DMA_CLOCK_ENABLE +#define LUOS_DMA_CLOCK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE(); +#endif +#ifndef LUOS_DMA +#define LUOS_DMA DMA2 +#endif +#ifndef LUOS_DMA_STREAM +#define LUOS_DMA_STREAM LL_DMA_STREAM_7 +#endif +#ifndef LUOS_DMA_CHANNEL +#define LUOS_DMA_CHANNEL LL_DMA_CHANNEL_4 +#endif +#ifndef LUOS_DMA_REMAP +#define LUOS_DMA_REMAP 0 +#endif /******************************************************************************* * COM TIMEOUT CONFIG ******************************************************************************/ diff --git a/STM32G4/luos_hal.c b/STM32G4/luos_hal.c index b2918f2..6a18bd6 100644 --- a/STM32G4/luos_hal.c +++ b/STM32G4/luos_hal.c @@ -12,25 +12,29 @@ #include "reception.h" #include "context.h" -//MCU dependencies this HAL is for family STM32l4 you can find +//MCU dependencies this HAL is for family STM32G4 you can find //the HAL stm32cubeg4 on ST web site #include "stm32g4xx_ll_usart.h" +#include "stm32g4xx_ll_gpio.h" +#include "stm32g4xx_ll_tim.h" +#include "stm32g4xx_ll_exti.h" +#include "stm32g4xx_ll_dma.h" +#include "stm32g4xx_ll_system.h" /******************************************************************************* * Definitions ******************************************************************************/ -#define TIMER_RELOAD_CNT 20 +#define DEFAULT_TIMEOUT 20 /******************************************************************************* * Variables ******************************************************************************/ -#ifdef STM32G4xx_HAL_CRC_H +#ifdef USE_CRC_HW CRC_HandleTypeDef hcrc; #endif GPIO_InitTypeDef GPIO_InitStruct = {0}; -TIM_HandleTypeDef TimerHandle = {0}; -uint32_t Timer_Prescaler = (MCUFREQ/DEFAULTBAUDRATE)/TIMERDIV;//(freq MCU/freq timer)/divider timer clock source +uint32_t Timer_Prescaler = (MCUFREQ / DEFAULTBAUDRATE) / TIMERDIV; //(freq MCU/freq timer)/divider timer clock source typedef struct { @@ -40,6 +44,9 @@ typedef struct } Port_t; Port_t PTP[NBR_PORT]; + +volatile uint16_t data_size_to_transmit = 0; +volatile uint8_t *tx_data = 0; /******************************************************************************* * Function ******************************************************************************/ @@ -47,12 +54,8 @@ static void LuosHAL_SystickInit(void); static void LuosHAL_FlashInit(void); static void LuosHAL_CRCInit(void); static void LuosHAL_TimeoutInit(void); -static void LuosHAL_ResetTimeout(void); -static inline void LuosHAL_ComTimeout(void); static void LuosHAL_GPIOInit(void); static void LuosHAL_FlashEraseLuosMemoryInfo(void); -static inline void LuosHAL_ComReceive(void); -static inline void LuosHAL_GPIOProcess(uint16_t GPIO); static void LuosHAL_RegisterPTP(void); /////////////////////////Luos Library Needed function/////////////////////////// @@ -123,7 +126,7 @@ void LuosHAL_ComInit(uint32_t Baudrate) LL_USART_InitTypeDef USART_InitStruct; - // Initialise USART3 + // Initialise USART1 LL_USART_Disable(LUOS_COM); USART_InitStruct.BaudRate = Baudrate; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; @@ -143,8 +146,22 @@ void LuosHAL_ComInit(uint32_t Baudrate) HAL_NVIC_SetPriority(LUOS_COM_IRQ, 0, 1); //Timeout Initialization - Timer_Prescaler = (MCUFREQ/Baudrate)/TIMERDIV; + Timer_Prescaler = (MCUFREQ / Baudrate) / TIMERDIV; LuosHAL_TimeoutInit(); + +#ifndef USE_TX_IT + LUOS_DMA_CLOCK_ENABLE(); + + LL_DMA_SetPeriphRequest(LUOS_DMA, LUOS_DMA_CHANNEL, LUOS_DMA_REQUEST); + LL_DMA_SetDataTransferDirection(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + LL_DMA_SetChannelPriorityLevel(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_PRIORITY_LOW); + LL_DMA_SetMode(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_MODE_NORMAL); + LL_DMA_SetPeriphIncMode(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetMemoryIncMode(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetPeriphSize(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_PDATAALIGN_BYTE); + LL_DMA_SetMemorySize(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_MDATAALIGN_BYTE); + LL_DMA_SetPeriphAddress(LUOS_DMA, LUOS_DMA_CHANNEL, (uint32_t)&LUOS_COM->TDR); +#endif } /****************************************************************************** * @brief Tx enable/disable relative to com @@ -155,19 +172,33 @@ void LuosHAL_SetTxState(uint8_t Enable) { if (Enable == true) { - COM_TX_PORT->OTYPER &= ~(uint32_t)(COM_TX_PIN);//put Tx in push pull - if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(TX_EN_PORT, TX_EN_PIN, GPIO_PIN_SET); - } + // Put Tx in push pull + LL_GPIO_SetPinOutputType(COM_TX_PORT, COM_TX_PIN, LL_GPIO_OUTPUT_PUSHPULL); + if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) + { + LL_GPIO_SetOutputPin(TX_EN_PORT, TX_EN_PIN); + } } else { - COM_TX_PORT->OTYPER |= (uint32_t)(COM_TX_PIN);//put Tx in Open drain - if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(TX_EN_PORT, TX_EN_PIN, GPIO_PIN_RESET); - } + // Put Tx in open drain + LL_USART_RequestTxDataFlush(LUOS_COM); + LL_GPIO_SetPinOutputType(COM_TX_PORT, COM_TX_PIN, LL_GPIO_OUTPUT_OPENDRAIN); + if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) + { + LL_GPIO_ResetOutputPin(TX_EN_PORT, TX_EN_PIN); + } +#ifdef USE_TX_IT + // Stop current transmit operation + data_size_to_transmit = 0; + // Disable Transmission empty buffer interrupt + LL_USART_DisableIT_TXE(LUOS_COM); +#else + LL_USART_DisableDMAReq_TX(LUOS_COM); + LL_DMA_DisableChannel(LUOS_DMA, LUOS_DMA_CHANNEL); +#endif + // Disable Transmission complete interrupt + LL_USART_DisableIT_TC(LUOS_COM); } } /****************************************************************************** @@ -179,89 +210,131 @@ void LuosHAL_SetRxState(uint8_t Enable) { if (Enable == true) { - LL_USART_ReceiveData8(LUOS_COM);//empty buffer - LUOS_COM->CR1 |= USART_CR1_RE;// Enable RX - LUOS_COM->CR1 |= USART_CR1_RXNEIE;//Enable RX IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(RX_EN_PORT, RX_EN_PIN, GPIO_PIN_RESET); - } + LL_USART_RequestRxDataFlush(LUOS_COM); // Clear data register + LL_USART_EnableDirectionRx(LUOS_COM); // Enable Rx com + LL_USART_EnableIT_RXNE(LUOS_COM); // Enable Rx IT } else { - LUOS_COM->CR1 &= ~USART_CR1_RE;// Disable RX - LUOS_COM->CR1 &= ~USART_CR1_RXNEIE;// Disable RX IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(RX_EN_PORT, RX_EN_PIN, GPIO_PIN_SET); - } + LL_USART_DisableDirectionRx(LUOS_COM); // Disable Rx com + LL_USART_DisableIT_RXNE(LUOS_COM); // Disable Rx IT } } /****************************************************************************** - * @brief Process data receive + * @brief Process data send or receive * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComReceive(void) +void LUOS_COM_IRQHANDLER() { - LuosHAL_ResetTimeout(); - + // Reset timeout to it's default value + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + // reception management if ((LL_USART_IsActiveFlag_RXNE(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_RXNE(LUOS_COM) != RESET)) { + // We receive a byte uint8_t data = LL_USART_ReceiveData8(LUOS_COM); ctx.rx.callback(&data); // send reception byte to state machine + if (data_size_to_transmit == 0) + { + LUOS_COM->ICR = 0xFFFFFFFF; + return; + } } else if (LL_USART_IsActiveFlag_FE(LUOS_COM) != RESET) { - LL_USART_ClearFlag_FE(LUOS_COM); + // Framing ERROR ctx.rx.status.rx_framing_error = true; } - else + + // Transmission management + if ((LL_USART_IsActiveFlag_TC(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_TC(LUOS_COM) != RESET)) { - LUOS_COM->ICR = 0xFFFFFFFF; + // Transmission complete + // Switch to reception mode + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); + // Disable transmission complete IRQ + LL_USART_ClearFlag_TC(LUOS_COM); + LL_USART_DisableIT_TC(LUOS_COM); } -} -/****************************************************************************** - * @brief Process data transmit - * @param None - * @return None - ******************************************************************************/ -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size) -{ - for (uint16_t i = 0; i < size; i++) +#ifdef USE_TX_IT + else if ((LL_USART_IsActiveFlag_TXE(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_TXE(LUOS_COM) != RESET)) { - ctx.tx.lock = true; - while (!LL_USART_IsActiveFlag_TXE(LUOS_COM)) + // Transmit buffer empty (this is a software DMA) + data_size_to_transmit--; + LL_USART_TransmitData8(LUOS_COM, *(tx_data++)); + if (data_size_to_transmit == 0) { + // Transmission complete, stop loading data and watch for the end of transmission + // Disable Transmission empty buffer interrupt + LL_USART_DisableIT_TXE(LUOS_COM); + // Enable Transmission complete interrupt + LL_USART_EnableIT_TC(LUOS_COM); } - if (ctx.tx.collision) - { - // There is a collision - ctx.tx.collision = FALSE; - return 1; - } - LL_USART_TransmitData8(LUOS_COM, *(data + i)); - LuosHAL_ResetTimeout(); } - __HAL_TIM_DISABLE_IT(&TimerHandle, TIM_IT_UPDATE); - return 0; +#endif + LUOS_COM->ICR = 0xFFFFFFFF; } /****************************************************************************** - * @brief Luos Tx communication complete + * @brief Process data transmit * @param None * @return None ******************************************************************************/ -void LuosHAL_ComTxComplete(void) +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size) { - while (!LL_USART_IsActiveFlag_TC(LUOS_COM)); - LuosHAL_ResetTimeout(); + while (LL_USART_IsActiveFlag_TXE(LUOS_COM) == RESET) + ; + // Disable RX detec pin if needed + // Enable TX + LuosHAL_SetTxState(true); + + // Reduce size by one because we send one directly + data_size_to_transmit = size - 1; + if (size > 1) + { + // Start the data buffer transmission + // **** NO DMA + //Copy the data pointer globally alowing to keep it and run the transmission. + tx_data = data; +#ifdef USE_TX_IT + // Send the first byte + LL_USART_TransmitData8(LUOS_COM, *(tx_data++)); + // Enable Transmission empty buffer interrupt to transmit next datas + LL_USART_EnableIT_TXE(LUOS_COM); + // Disable Transmission complete interrupt + LL_USART_DisableIT_TC(LUOS_COM); +#else + data_size_to_transmit = 0;//to not check IT TC during collision + // Disable DMA to load new length to be tranmitted + LL_DMA_DisableChannel(LUOS_DMA, LUOS_DMA_CHANNEL); + // configure address to be transmitted by DMA + LL_DMA_SetMemoryAddress(LUOS_DMA, LUOS_DMA_CHANNEL, (uint32_t)data); + // set length to be tranmitted + LL_DMA_SetDataLength(LUOS_DMA, LUOS_DMA_CHANNEL, size); + // set request DMA + LL_USART_EnableDMAReq_TX(LUOS_COM); + // Enable DMA again + LL_DMA_EnableChannel(LUOS_DMA, LUOS_DMA_CHANNEL); + // enable transmit complete + LL_USART_EnableIT_TC(LUOS_COM); +#endif + } + else + { + // Transmit the only byte we have + LL_USART_TransmitData8(LUOS_COM, *data); + // Enable Transmission complete interrupt because we only have one. + LL_USART_EnableIT_TC(LUOS_COM); + } + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } /****************************************************************************** * @brief set state of Txlock detection pin * @param None * @return Lock status ******************************************************************************/ -void LuosHAL_SetTxLockDetecState(uint8_t Enable) +void LuosHAL_SetRxDetecPin(uint8_t Enable) { if (TX_LOCK_DETECT_IRQ != DISABLE) { @@ -272,7 +345,7 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) } else { - EXTI->IMR1 &= ~ TX_LOCK_DETECT_PIN; + EXTI->IMR1 &= ~TX_LOCK_DETECT_PIN; } } } @@ -284,26 +357,29 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) uint8_t LuosHAL_GetTxLockState(void) { uint8_t result = false; - - #ifdef USART_ISR_BUSY - if (READ_BIT(LUOS_COM->ISR, USART_ISR_BUSY) == (USART_ISR_BUSY)) + +#ifdef USART_ISR_BUSY + if (LL_USART_IsActiveFlag_BUSY(LUOS_COM) == true) { - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); result = true; } - #else +#else if ((TX_LOCK_DETECT_PIN != DISABLE) && (TX_LOCK_DETECT_PORT != DISABLE)) { - if(TX_LOCK_DETECT_IRQ == DISABLE) + if(HAL_GPIO_ReadPin(TX_LOCK_DETECT_PORT, TX_LOCK_DETECT_PIN) == GPIO_PIN_RESET) { - result = HAL_GPIO_ReadPin(TX_LOCK_DETECT_PORT, TX_LOCK_DETECT_PIN); - if(result == true) + result = true; + } + if (TX_LOCK_DETECT_IRQ == DISABLE) + { + if (result == true) { - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } } } - #endif +#endif return result; } /****************************************************************************** @@ -313,51 +389,55 @@ uint8_t LuosHAL_GetTxLockState(void) ******************************************************************************/ static void LuosHAL_TimeoutInit(void) { + LL_TIM_InitTypeDef TimerInit = {0}; + //initialize clock LUOS_TIMER_CLOCK_ENABLE(); - TimerHandle.Instance = LUOS_TIMER; - TimerHandle.Init.Period = TIMER_RELOAD_CNT; - TimerHandle.Init.Prescaler = Timer_Prescaler-1; - TimerHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - TimerHandle.Init.CounterMode = TIM_COUNTERMODE_UP; - TimerHandle.Init.RepetitionCounter = 0; - TimerHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - if(HAL_TIM_Base_Init(&TimerHandle) != HAL_OK) - { - while(1); - } + TimerInit.Autoreload = DEFAULT_TIMEOUT; + TimerInit.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TimerInit.CounterMode = LL_TIM_COUNTERMODE_UP; + TimerInit.Prescaler = Timer_Prescaler - 1; + TimerInit.RepetitionCounter = 0; + while (LL_TIM_Init(LUOS_TIMER, &TimerInit) != SUCCESS) + ; + LL_TIM_EnableIT_UPDATE(LUOS_TIMER); HAL_NVIC_SetPriority(LUOS_TIMER_IRQ, 0, 2); HAL_NVIC_EnableIRQ(LUOS_TIMER_IRQ); } /****************************************************************************** - * @brief Luos Timeout for Rx communication + * @brief Luos Timeout communication * @param None * @return None ******************************************************************************/ -static void LuosHAL_ResetTimeout(void) +void LuosHAL_ResetTimeout(uint16_t nbrbit) { - LUOS_TIMER->CR1 &= ~(TIM_CR1_CEN);//disable counter - NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// clear IT pending - __HAL_TIM_CLEAR_IT(&TimerHandle, TIM_IT_UPDATE);// clear IT flag - LUOS_TIMER->CNT = 0;//reset counter - LUOS_TIMER->ARR = TIMER_RELOAD_CNT;//relaod value - __HAL_TIM_ENABLE_IT(&TimerHandle, TIM_IT_UPDATE); - LUOS_TIMER->CR1 |= TIM_CR1_CEN;//enable counter + LL_TIM_DisableCounter(LUOS_TIMER); + NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// Clear IT pending NVIC + LL_TIM_ClearFlag_UPDATE(LUOS_TIMER); + LL_TIM_SetCounter(LUOS_TIMER, 0);// Reset counter + if(nbrbit != 0) + { + LL_TIM_SetAutoReload(LUOS_TIMER, nbrbit);//reload value + LL_TIM_EnableCounter(LUOS_TIMER); + } } /****************************************************************************** - * @brief Luos Timeout for Rx communication + * @brief Luos Timeout communication * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComTimeout(void) +void LUOS_TIMER_IRQHANDLER() { - if (__HAL_TIM_GET_FLAG(&TimerHandle, TIM_FLAG_UPDATE) != RESET) + if (LL_TIM_IsActiveFlag_UPDATE(LUOS_TIMER) != RESET) { - __HAL_TIM_CLEAR_IT(&TimerHandle, TIM_IT_UPDATE); - LUOS_TIMER->CR1 &= ~(TIM_CR1_CEN); - if (ctx.tx.lock == true) + LL_TIM_ClearFlag_UPDATE(LUOS_TIMER); + LL_TIM_DisableCounter(LUOS_TIMER); + if ((ctx.tx.lock == true)&&(LuosHAL_GetTxLockState() == false)) { + // Enable RX detection pin if needed + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); Recep_Timeout(); } } @@ -374,36 +454,22 @@ static void LuosHAL_GPIOInit(void) if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : RxEN_Pin */ - GPIO_InitStruct.Pin = RX_EN_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(RX_EN_PORT, &GPIO_InitStruct); + /*Configure GPIO pins : RxEN_Pin */ + GPIO_InitStruct.Pin = RX_EN_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(RX_EN_PORT, &GPIO_InitStruct); } if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : TxEN_Pin */ - GPIO_InitStruct.Pin = TX_EN_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(TX_EN_PORT, &GPIO_InitStruct); - } - - /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ - GPIO_InitStruct.Pin = TX_LOCK_DETECT_PIN; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) - { - if (TX_LOCK_DETECT_IRQ != DISABLE) - { - GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; - } - HAL_GPIO_Init(TX_LOCK_DETECT_PORT, &GPIO_InitStruct); + /*Configure GPIO pins : TxEN_Pin */ + GPIO_InitStruct.Pin = TX_EN_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(TX_EN_PORT, &GPIO_InitStruct); } /*Configure GPIO pin : TxPin */ @@ -438,11 +504,20 @@ static void LuosHAL_GPIOInit(void) HAL_NVIC_EnableIRQ(PTP[i].IRQ); } - if (TX_LOCK_DETECT_IRQ != DISABLE) + if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) { - EXTI->IMR1 &= ~ TX_LOCK_DETECT_PIN; - HAL_NVIC_SetPriority(TX_LOCK_DETECT_IRQ, 1, 0); - HAL_NVIC_EnableIRQ(TX_LOCK_DETECT_IRQ); + /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ + GPIO_InitStruct.Pin = TX_LOCK_DETECT_PIN; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + if (TX_LOCK_DETECT_IRQ != DISABLE) + { + GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; + HAL_NVIC_SetPriority(TX_LOCK_DETECT_IRQ, 1, 0); + HAL_NVIC_EnableIRQ(TX_LOCK_DETECT_IRQ); + } + HAL_GPIO_Init(TX_LOCK_DETECT_PORT, &GPIO_InitStruct); } } /****************************************************************************** @@ -481,20 +556,20 @@ static void LuosHAL_RegisterPTP(void) * @param GPIO IT line * @return None ******************************************************************************/ -static inline void LuosHAL_GPIOProcess(uint16_t GPIO) +void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) { ////Process for Tx Lock Detec - if (GPIO == TX_LOCK_DETECT_PIN) + if ((GPIO_Pin == TX_LOCK_DETECT_PIN)&&(TX_LOCK_DETECT_IRQ != DISABLE)) { ctx.tx.lock = true; - LuosHAL_ResetTimeout(); - EXTI->IMR1 &= ~ TX_LOCK_DETECT_PIN; + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + EXTI->IMR1 &= ~TX_LOCK_DETECT_PIN; } else { for (uint8_t i = 0; i < NBR_PORT; i++) { - if (GPIO == PTP[i].Pin) + if (GPIO_Pin == PTP[i].Pin) { PortMng_PtpHandler(i); break; @@ -561,7 +636,7 @@ uint8_t LuosHAL_GetPTPState(uint8_t PTPNbr) ******************************************************************************/ static void LuosHAL_CRCInit(void) { -#ifdef STM32G4xx_HAL_CRC_H +#ifdef USE_CRC_HW __HAL_RCC_CRC_CLK_ENABLE(); hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; @@ -585,24 +660,19 @@ static void LuosHAL_CRCInit(void) ******************************************************************************/ void LuosHAL_ComputeCRC(uint8_t *data, uint8_t *crc) { -#ifdef STM32G4xx_HAL_CRC_H - LuosHAL_SetIrqState(false); +#ifdef USE_CRC_HW hcrc.Instance->INIT = *(uint16_t *)crc; __HAL_CRC_DR_RESET(&hcrc); *(uint16_t *)crc = (uint16_t)HAL_CRC_Accumulate(&hcrc, (uint32_t *)data, 1); - LuosHAL_SetIrqState(true); #else - for (uint8_t i = 0; i < 1; ++i) + uint16_t dbyte = *data; + *(uint16_t *)crc ^= dbyte << 8; + for (uint8_t j = 0; j < 8; ++j) { - uint16_t dbyte = data[i]; - *(uint16_t *)crc ^= dbyte << 8; - for (uint8_t j = 0; j < 8; ++j) - { - uint16_t mix = *(uint16_t *)crc & 0x8000; - *(uint16_t *)crc = (*(uint16_t *)crc << 1); - if (mix) - *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; - } + uint16_t mix = *(uint16_t *)crc & 0x8000; + *(uint16_t *)crc = (*(uint16_t *)crc << 1); + if (mix) + *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; } #endif } @@ -672,17 +742,3 @@ void LuosHAL_FlashReadLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *data { memcpy(data, (void *)(addr), size); } - -/////////////////////////Special LuosHAL function/////////////////////////// -void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) -{ - LuosHAL_GPIOProcess(GPIO_Pin); -} -void LUOS_COM_IRQHANDLER() -{ - LuosHAL_ComReceive(); -} -void LUOS_TIMER_IRQHANDLER() -{ - LuosHAL_ComTimeout(); -} diff --git a/STM32G4/luos_hal.h b/STM32G4/luos_hal.h index 79fe855..4896fbd 100644 --- a/STM32G4/luos_hal.h +++ b/STM32G4/luos_hal.h @@ -1,7 +1,7 @@ /****************************************************************************** * @file luosHAL * @brief Luos Hardware Abstration Layer. Describe Low layer fonction - * @MCU Family STM32FO + * @MCU Family STM32G4 * @author Luos * @version 0.0.0 ******************************************************************************/ @@ -37,10 +37,10 @@ uint32_t LuosHAL_GetSystick(void); void LuosHAL_ComInit(uint32_t Baudrate); void LuosHAL_SetTxState(uint8_t Enable); void LuosHAL_SetRxState(uint8_t Enable); -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size); -void LuosHAL_SetTxLockDetecState(uint8_t Enable); +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size); uint8_t LuosHAL_GetTxLockState(void); -void LuosHAL_ComTxComplete(void); +void LuosHAL_SetRxDetecPin(uint8_t Enable); +void LuosHAL_ResetTimeout(uint16_t nbrbit); void LuosHAL_SetPTPDefaultState(uint8_t PTPNbr); void LuosHAL_SetPTPReverseState(uint8_t PTPNbr); void LuosHAL_PushPTP(uint8_t PTPNbr); diff --git a/STM32G4/luos_hal_config.h b/STM32G4/luos_hal_config.h index 8813204..ada4076 100644 --- a/STM32G4/luos_hal_config.h +++ b/STM32G4/luos_hal_config.h @@ -12,6 +12,9 @@ #include "stm32g4xx_hal.h" +//If your MCU do not Have DMA for tx transmit define USE_TX_IT +#define USE_CRC_HW + #define DISABLE 0x00 #ifndef MCUFREQ @@ -117,6 +120,21 @@ #ifndef LUOS_COM_IRQHANDLER #define LUOS_COM_IRQHANDLER() USART1_IRQHandler() #endif +/******************************************************************************* + * FLASH CONFIG + ******************************************************************************/ +#ifndef LUOS_DMA_CLOCK_ENABLE +#define LUOS_DMA_CLOCK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE(); +#endif +#ifndef LUOS_DMA +#define LUOS_DMA DMA1 +#endif +#ifndef LUOS_DMA_CHANNEL +#define LUOS_DMA_CHANNEL LL_DMA_CHANNEL_1 +#endif +#ifndef LUOS_DMA_REQUEST +#define LUOS_DMA_REQUEST LL_DMAMUX_REQ_USART1_TX +#endif /******************************************************************************* * COM TIMEOUT CONFIG ******************************************************************************/ diff --git a/STM32L4/luos_hal.c b/STM32L4/luos_hal.c index 4ed5d16..423dbd7 100644 --- a/STM32L4/luos_hal.c +++ b/STM32L4/luos_hal.c @@ -15,22 +15,26 @@ //MCU dependencies this HAL is for family STM32l4 you can find //the HAL stm32cubel4 on ST web site #include "stm32l4xx_ll_usart.h" +#include "stm32l4xx_ll_gpio.h" +#include "stm32l4xx_ll_tim.h" +#include "stm32l4xx_ll_exti.h" +#include "stm32l4xx_ll_dma.h" +#include "stm32l4xx_ll_system.h" /******************************************************************************* * Definitions ******************************************************************************/ -#define TIMER_RELOAD_CNT 20 +#define DEFAULT_TIMEOUT 20 /******************************************************************************* * Variables ******************************************************************************/ -#ifdef STM32L4xx_HAL_CRC_H +#ifdef USE_CRC_HW CRC_HandleTypeDef hcrc; #endif GPIO_InitTypeDef GPIO_InitStruct = {0}; -TIM_HandleTypeDef TimerHandle = {0}; -uint32_t Timer_Prescaler = (MCUFREQ/DEFAULTBAUDRATE)/TIMERDIV;//(freq MCU/freq timer)/divider timer clock source +uint32_t Timer_Prescaler = (MCUFREQ / DEFAULTBAUDRATE) / TIMERDIV; //(freq MCU/freq timer)/divider timer clock source typedef struct { @@ -40,6 +44,9 @@ typedef struct } Port_t; Port_t PTP[NBR_PORT]; + +volatile uint16_t data_size_to_transmit = 0; +volatile uint8_t *tx_data = 0; /******************************************************************************* * Function ******************************************************************************/ @@ -47,12 +54,8 @@ static void LuosHAL_SystickInit(void); static void LuosHAL_FlashInit(void); static void LuosHAL_CRCInit(void); static void LuosHAL_TimeoutInit(void); -static void LuosHAL_ResetTimeout(void); -static inline void LuosHAL_ComTimeout(void); static void LuosHAL_GPIOInit(void); static void LuosHAL_FlashEraseLuosMemoryInfo(void); -static inline void LuosHAL_ComReceive(void); -static inline void LuosHAL_GPIOProcess(uint16_t GPIO); static void LuosHAL_RegisterPTP(void); /////////////////////////Luos Library Needed function/////////////////////////// @@ -123,7 +126,7 @@ void LuosHAL_ComInit(uint32_t Baudrate) LL_USART_InitTypeDef USART_InitStruct; - // Initialise USART3 + // Initialise USART1 LL_USART_Disable(LUOS_COM); USART_InitStruct.BaudRate = Baudrate; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; @@ -143,8 +146,22 @@ void LuosHAL_ComInit(uint32_t Baudrate) HAL_NVIC_SetPriority(LUOS_COM_IRQ, 0, 1); //Timeout Initialization - Timer_Prescaler = (MCUFREQ/Baudrate)/TIMERDIV; + Timer_Prescaler = (MCUFREQ / Baudrate) / TIMERDIV; LuosHAL_TimeoutInit(); + +#ifndef USE_TX_IT + LUOS_DMA_CLOCK_ENABLE(); + + LL_DMA_SetPeriphRequest(LUOS_DMA, LUOS_DMA_CHANNEL, LUOS_DMA_REQUEST); + LL_DMA_SetDataTransferDirection(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + LL_DMA_SetChannelPriorityLevel(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_PRIORITY_LOW); + LL_DMA_SetMode(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_MODE_NORMAL); + LL_DMA_SetPeriphIncMode(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetMemoryIncMode(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetPeriphSize(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_PDATAALIGN_BYTE); + LL_DMA_SetMemorySize(LUOS_DMA, LUOS_DMA_CHANNEL, LL_DMA_MDATAALIGN_BYTE); + LL_DMA_SetPeriphAddress(LUOS_DMA, LUOS_DMA_CHANNEL, (uint32_t)&LUOS_COM->TDR); +#endif } /****************************************************************************** * @brief Tx enable/disable relative to com @@ -155,19 +172,33 @@ void LuosHAL_SetTxState(uint8_t Enable) { if (Enable == true) { - COM_TX_PORT->OTYPER &= ~(uint32_t)(COM_TX_PIN);//put Tx in push pull + // Put Tx in push pull + LL_GPIO_SetPinOutputType(COM_TX_PORT, COM_TX_PIN, LL_GPIO_OUTPUT_PUSHPULL); if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) { - HAL_GPIO_WritePin(TX_EN_PORT, TX_EN_PIN, GPIO_PIN_SET); + LL_GPIO_SetOutputPin(TX_EN_PORT, TX_EN_PIN); } } else { - COM_TX_PORT->OTYPER |= (uint32_t)(COM_TX_PIN);//put Tx in Open drain + // Put Tx in open drain + LL_USART_RequestTxDataFlush(LUOS_COM); + LL_GPIO_SetPinOutputType(COM_TX_PORT, COM_TX_PIN, LL_GPIO_OUTPUT_OPENDRAIN); if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) { - HAL_GPIO_WritePin(TX_EN_PORT, TX_EN_PIN, GPIO_PIN_RESET); + LL_GPIO_ResetOutputPin(TX_EN_PORT, TX_EN_PIN); } +#ifdef USE_TX_IT + // Stop current transmit operation + data_size_to_transmit = 0; + // Disable Transmission empty buffer interrupt + LL_USART_DisableIT_TXE(LUOS_COM); +#else + LL_USART_DisableDMAReq_TX(LUOS_COM); + LL_DMA_DisableChannel(LUOS_DMA, LUOS_DMA_CHANNEL); +#endif + // Disable Transmission complete interrupt + LL_USART_DisableIT_TC(LUOS_COM); } } /****************************************************************************** @@ -179,91 +210,133 @@ void LuosHAL_SetRxState(uint8_t Enable) { if (Enable == true) { - LL_USART_ReceiveData8(LUOS_COM);//empty buffer - LUOS_COM->CR1 |= USART_CR1_RE;// Enable RX - LUOS_COM->CR1 |= USART_CR1_RXNEIE;//Enable RX IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(RX_EN_PORT, RX_EN_PIN, GPIO_PIN_RESET); - } + LL_USART_RequestRxDataFlush(LUOS_COM); // Clear data register + LL_USART_EnableDirectionRx(LUOS_COM); // Enable Rx com + LL_USART_EnableIT_RXNE(LUOS_COM); // Enable Rx IT } else { - LUOS_COM->CR1 &= ~USART_CR1_RE;// Disable RX - LUOS_COM->CR1 &= ~USART_CR1_RXNEIE;// Disable RX IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - HAL_GPIO_WritePin(RX_EN_PORT, RX_EN_PIN, GPIO_PIN_SET); - } + LL_USART_DisableDirectionRx(LUOS_COM); // Disable Rx com + LL_USART_DisableIT_RXNE(LUOS_COM); // Disable Rx IT } } /****************************************************************************** - * @brief Process data receive + * @brief Process data send or receive * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComReceive(void) +void LUOS_COM_IRQHANDLER() { - LuosHAL_ResetTimeout(); - + // Reset timeout to it's default value + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + // reception management if ((LL_USART_IsActiveFlag_RXNE(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_RXNE(LUOS_COM) != RESET)) { + // We receive a byte uint8_t data = LL_USART_ReceiveData8(LUOS_COM); ctx.rx.callback(&data); // send reception byte to state machine + if (data_size_to_transmit == 0) + { + LUOS_COM->ICR = 0xFFFFFFFF; + return; + } } else if (LL_USART_IsActiveFlag_FE(LUOS_COM) != RESET) { - LL_USART_ClearFlag_FE(LUOS_COM); + // Framing ERROR ctx.rx.status.rx_framing_error = true; } - else + + // Transmission management + if ((LL_USART_IsActiveFlag_TC(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_TC(LUOS_COM) != RESET)) { - LUOS_COM->ICR = 0xFFFFFFFF; + // Transmission complete + // Switch to reception mode + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); + // Disable transmission complete IRQ + LL_USART_ClearFlag_TC(LUOS_COM); + LL_USART_DisableIT_TC(LUOS_COM); } -} -/****************************************************************************** - * @brief Process data transmit - * @param None - * @return None - ******************************************************************************/ -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size) -{ - for (uint16_t i = 0; i < size; i++) +#ifdef USE_TX_IT + else if ((LL_USART_IsActiveFlag_TXE(LUOS_COM) != RESET) && (LL_USART_IsEnabledIT_TXE(LUOS_COM) != RESET)) { - ctx.tx.lock = true; - while (!LL_USART_IsActiveFlag_TXE(LUOS_COM)) - { - } - if (ctx.tx.collision) + // Transmit buffer empty (this is a software DMA) + data_size_to_transmit--; + LL_USART_TransmitData8(LUOS_COM, *(tx_data++)); + if (data_size_to_transmit == 0) { - // There is a collision - ctx.tx.collision = FALSE; - return 1; + // Transmission complete, stop loading data and watch for the end of transmission + // Disable Transmission empty buffer interrupt + LL_USART_DisableIT_TXE(LUOS_COM); + // Enable Transmission complete interrupt + LL_USART_EnableIT_TC(LUOS_COM); } - LL_USART_TransmitData8(LUOS_COM, *(data + i)); - LuosHAL_ResetTimeout(); } - __HAL_TIM_DISABLE_IT(&TimerHandle, TIM_IT_UPDATE); - return 0; +#endif + LUOS_COM->ICR = 0xFFFFFFFF; } /****************************************************************************** - * @brief Luos Tx communication complete + * @brief Process data transmit * @param None * @return None ******************************************************************************/ -void LuosHAL_ComTxComplete(void) +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size) { - while (!LL_USART_IsActiveFlag_TC(LUOS_COM)); - LuosHAL_ResetTimeout(); + while (LL_USART_IsActiveFlag_TXE(LUOS_COM) == RESET) + ; + // Disable RX detec pin if needed + // Enable TX + LuosHAL_SetTxState(true); + + // Reduce size by one because we send one directly + data_size_to_transmit = size - 1; + if (size > 1) + { + // Start the data buffer transmission + // **** NO DMA + //Copy the data pointer globally alowing to keep it and run the transmission. + tx_data = data; +#ifdef USE_TX_IT + // Send the first byte + LL_USART_TransmitData8(LUOS_COM, *(tx_data++)); + // Enable Transmission empty buffer interrupt to transmit next datas + LL_USART_EnableIT_TXE(LUOS_COM); + // Disable Transmission complete interrupt + LL_USART_DisableIT_TC(LUOS_COM); +#else + data_size_to_transmit = 0;//to not check IT TC during collision + // Disable DMA to load new length to be tranmitted + LL_DMA_DisableChannel(LUOS_DMA, LUOS_DMA_CHANNEL); + // configure address to be transmitted by DMA + LL_DMA_SetMemoryAddress(LUOS_DMA, LUOS_DMA_CHANNEL, (uint32_t)data); + // set length to be tranmitted + LL_DMA_SetDataLength(LUOS_DMA, LUOS_DMA_CHANNEL, size); + // set request DMA + LL_USART_EnableDMAReq_TX(LUOS_COM); + // Enable DMA again + LL_DMA_EnableChannel(LUOS_DMA, LUOS_DMA_CHANNEL); + // enable transmit complete + LL_USART_EnableIT_TC(LUOS_COM); +#endif + } + else + { + // Transmit the only byte we have + LL_USART_TransmitData8(LUOS_COM, *data); + // Enable Transmission complete interrupt because we only have one. + LL_USART_EnableIT_TC(LUOS_COM); + } + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } /****************************************************************************** * @brief set state of Txlock detection pin * @param None * @return Lock status ******************************************************************************/ -void LuosHAL_SetTxLockDetecState(uint8_t Enable) +void LuosHAL_SetRxDetecPin(uint8_t Enable) { - if (TX_LOCK_DETECT_IRQ != DISABLE) + if (TX_LOCK_DETECT_IRQ != DISABLE) { __HAL_GPIO_EXTI_CLEAR_IT(TX_LOCK_DETECT_IRQ); if (Enable == true) @@ -272,7 +345,7 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) } else { - EXTI->IMR1 &= ~ TX_LOCK_DETECT_PIN; + EXTI->IMR1 &= ~TX_LOCK_DETECT_PIN; } } } @@ -284,26 +357,29 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) uint8_t LuosHAL_GetTxLockState(void) { uint8_t result = false; - - #ifdef USART_ISR_BUSY - if (READ_BIT(LUOS_COM->ISR, USART_ISR_BUSY) == (USART_ISR_BUSY)) + +#ifdef USART_ISR_BUSY + if (LL_USART_IsActiveFlag_BUSY(LUOS_COM) == true) { - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); result = true; } - #else +#else if ((TX_LOCK_DETECT_PIN != DISABLE) && (TX_LOCK_DETECT_PORT != DISABLE)) { - if(TX_LOCK_DETECT_IRQ == DISABLE) + if(HAL_GPIO_ReadPin(TX_LOCK_DETECT_PORT, TX_LOCK_DETECT_PIN) == GPIO_PIN_RESET) { - result = HAL_GPIO_ReadPin(TX_LOCK_DETECT_PORT, TX_LOCK_DETECT_PIN); - if(result == true) + result = true; + } + if (TX_LOCK_DETECT_IRQ == DISABLE) + { + if (result == true) { - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } } } - #endif +#endif return result; } /****************************************************************************** @@ -313,51 +389,55 @@ uint8_t LuosHAL_GetTxLockState(void) ******************************************************************************/ static void LuosHAL_TimeoutInit(void) { + LL_TIM_InitTypeDef TimerInit = {0}; + //initialize clock LUOS_TIMER_CLOCK_ENABLE(); - TimerHandle.Instance = LUOS_TIMER; - TimerHandle.Init.Period = TIMER_RELOAD_CNT; - TimerHandle.Init.Prescaler = Timer_Prescaler-1; - TimerHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - TimerHandle.Init.CounterMode = TIM_COUNTERMODE_UP; - TimerHandle.Init.RepetitionCounter = 0; - TimerHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - if(HAL_TIM_Base_Init(&TimerHandle) != HAL_OK) - { - while(1); - } + TimerInit.Autoreload = DEFAULT_TIMEOUT; + TimerInit.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TimerInit.CounterMode = LL_TIM_COUNTERMODE_UP; + TimerInit.Prescaler = Timer_Prescaler - 1; + TimerInit.RepetitionCounter = 0; + while (LL_TIM_Init(LUOS_TIMER, &TimerInit) != SUCCESS) + ; + LL_TIM_EnableIT_UPDATE(LUOS_TIMER); HAL_NVIC_SetPriority(LUOS_TIMER_IRQ, 0, 2); HAL_NVIC_EnableIRQ(LUOS_TIMER_IRQ); } /****************************************************************************** - * @brief Luos Timeout for Rx communication + * @brief Luos Timeout communication * @param None * @return None ******************************************************************************/ -static void LuosHAL_ResetTimeout(void) +void LuosHAL_ResetTimeout(uint16_t nbrbit) { - LUOS_TIMER->CR1 &= ~(TIM_CR1_CEN);//disable counter - NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// clear IT pending - __HAL_TIM_CLEAR_IT(&TimerHandle, TIM_IT_UPDATE);// clear IT flag - LUOS_TIMER->CNT = 0;//reset counter - LUOS_TIMER->ARR = TIMER_RELOAD_CNT;//relaod value - __HAL_TIM_ENABLE_IT(&TimerHandle, TIM_IT_UPDATE); - LUOS_TIMER->CR1 |= TIM_CR1_CEN;//enable counter + LL_TIM_DisableCounter(LUOS_TIMER); + NVIC_ClearPendingIRQ(LUOS_TIMER_IRQ);// Clear IT pending NVIC + LL_TIM_ClearFlag_UPDATE(LUOS_TIMER); + LL_TIM_SetCounter(LUOS_TIMER, 0);// Reset counter + if(nbrbit != 0) + { + LL_TIM_SetAutoReload(LUOS_TIMER, nbrbit);//reload value + LL_TIM_EnableCounter(LUOS_TIMER); + } } /****************************************************************************** - * @brief Luos Timeout for Rx communication + * @brief Luos Timeout communication * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComTimeout(void) +void LUOS_TIMER_IRQHANDLER() { - if (__HAL_TIM_GET_FLAG(&TimerHandle, TIM_FLAG_UPDATE) != RESET) + if (LL_TIM_IsActiveFlag_UPDATE(LUOS_TIMER) != RESET) { - __HAL_TIM_CLEAR_IT(&TimerHandle, TIM_IT_UPDATE); - LUOS_TIMER->CR1 &= ~(TIM_CR1_CEN); - if (ctx.tx.lock == true) + LL_TIM_ClearFlag_UPDATE(LUOS_TIMER); + LL_TIM_DisableCounter(LUOS_TIMER); + if ((ctx.tx.lock == true)&&(LuosHAL_GetTxLockState() == false)) { + // Enable RX detection pin if needed + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); Recep_Timeout(); } } @@ -392,20 +472,6 @@ static void LuosHAL_GPIOInit(void) HAL_GPIO_Init(TX_EN_PORT, &GPIO_InitStruct); } - /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ - GPIO_InitStruct.Pin = TX_LOCK_DETECT_PIN; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) - { - if (TX_LOCK_DETECT_IRQ != DISABLE) - { - GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; - } - HAL_GPIO_Init(TX_LOCK_DETECT_PORT, &GPIO_InitStruct); - } - /*Configure GPIO pin : TxPin */ GPIO_InitStruct.Pin = COM_TX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; @@ -438,11 +504,20 @@ static void LuosHAL_GPIOInit(void) HAL_NVIC_EnableIRQ(PTP[i].IRQ); } - if (TX_LOCK_DETECT_IRQ != DISABLE) + if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) { - EXTI->IMR1 &= ~ TX_LOCK_DETECT_PIN; - HAL_NVIC_SetPriority(TX_LOCK_DETECT_IRQ, 1, 0); - HAL_NVIC_EnableIRQ(TX_LOCK_DETECT_IRQ); + /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ + GPIO_InitStruct.Pin = TX_LOCK_DETECT_PIN; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + if (TX_LOCK_DETECT_IRQ != DISABLE) + { + GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; + HAL_NVIC_SetPriority(TX_LOCK_DETECT_IRQ, 1, 0); + HAL_NVIC_EnableIRQ(TX_LOCK_DETECT_IRQ); + } + HAL_GPIO_Init(TX_LOCK_DETECT_PORT, &GPIO_InitStruct); } } /****************************************************************************** @@ -481,20 +556,20 @@ static void LuosHAL_RegisterPTP(void) * @param GPIO IT line * @return None ******************************************************************************/ -static inline void LuosHAL_GPIOProcess(uint16_t GPIO) +void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) { ////Process for Tx Lock Detec - if (GPIO == TX_LOCK_DETECT_PIN) + if ((GPIO_Pin == TX_LOCK_DETECT_PIN)&&(TX_LOCK_DETECT_IRQ != DISABLE)) { - ctx.tx.lock = true; - LuosHAL_ResetTimeout(); - EXTI->IMR1 &= ~ TX_LOCK_DETECT_PIN; + ctx.tx.lock = true; + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); + EXTI->IMR1 &= ~TX_LOCK_DETECT_PIN; } else { for (uint8_t i = 0; i < NBR_PORT; i++) { - if (GPIO == PTP[i].Pin) + if (GPIO_Pin == PTP[i].Pin) { PortMng_PtpHandler(i); break; @@ -561,7 +636,7 @@ uint8_t LuosHAL_GetPTPState(uint8_t PTPNbr) ******************************************************************************/ static void LuosHAL_CRCInit(void) { -#ifdef STM32L4xx_HAL_CRC_H +#ifdef USE_CRC_HW __HAL_RCC_CRC_CLK_ENABLE(); hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; @@ -585,24 +660,19 @@ static void LuosHAL_CRCInit(void) ******************************************************************************/ void LuosHAL_ComputeCRC(uint8_t *data, uint8_t *crc) { -#ifdef STM32L4xx_HAL_CRC_H - LuosHAL_SetIrqState(false); +#ifdef USE_CRC_HW hcrc.Instance->INIT = *(uint16_t *)crc; __HAL_CRC_DR_RESET(&hcrc); *(uint16_t *)crc = (uint16_t)HAL_CRC_Accumulate(&hcrc, (uint32_t *)data, 1); - LuosHAL_SetIrqState(true); #else - for (uint8_t i = 0; i < 1; ++i) + uint16_t dbyte = *data; + *(uint16_t *)crc ^= dbyte << 8; + for (uint8_t j = 0; j < 8; ++j) { - uint16_t dbyte = data[i]; - *(uint16_t *)crc ^= dbyte << 8; - for (uint8_t j = 0; j < 8; ++j) - { - uint16_t mix = *(uint16_t *)crc & 0x8000; - *(uint16_t *)crc = (*(uint16_t *)crc << 1); - if (mix) - *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; - } + uint16_t mix = *(uint16_t *)crc & 0x8000; + *(uint16_t *)crc = (*(uint16_t *)crc << 1); + if (mix) + *(uint16_t *)crc = *(uint16_t *)crc ^ 0x0007; } #endif } @@ -672,17 +742,3 @@ void LuosHAL_FlashReadLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *data { memcpy(data, (void *)(addr), size); } - -/////////////////////////Special LuosHAL function/////////////////////////// -void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) -{ - LuosHAL_GPIOProcess(GPIO_Pin); -} -void LUOS_COM_IRQHANDLER() -{ - LuosHAL_ComReceive(); -} -void LUOS_TIMER_IRQHANDLER() -{ - LuosHAL_ComTimeout(); -} diff --git a/STM32L4/luos_hal.h b/STM32L4/luos_hal.h index b44a7db..18b78d9 100644 --- a/STM32L4/luos_hal.h +++ b/STM32L4/luos_hal.h @@ -35,10 +35,10 @@ uint32_t LuosHAL_GetSystick(void); void LuosHAL_ComInit(uint32_t Baudrate); void LuosHAL_SetTxState(uint8_t Enable); void LuosHAL_SetRxState(uint8_t Enable); -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size); -void LuosHAL_SetTxLockDetecState(uint8_t Enable); +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size); uint8_t LuosHAL_GetTxLockState(void); -void LuosHAL_ComTxComplete(void); +void LuosHAL_SetRxDetecPin(uint8_t Enable); +void LuosHAL_ResetTimeout(uint16_t nbrbit); void LuosHAL_SetPTPDefaultState(uint8_t PTPNbr); void LuosHAL_SetPTPReverseState(uint8_t PTPNbr); void LuosHAL_PushPTP(uint8_t PTPNbr); diff --git a/STM32L4/luos_hal_config.h b/STM32L4/luos_hal_config.h index 15a7aa9..fc9f0c9 100644 --- a/STM32L4/luos_hal_config.h +++ b/STM32L4/luos_hal_config.h @@ -12,6 +12,9 @@ #include "stm32l4xx_hal.h" +//If your MCU do not Have DMA for tx transmit define USE_TX_IT +#define USE_CRC_HW + #define DISABLE 0x00 #ifndef MCUFREQ @@ -117,6 +120,21 @@ #ifndef LUOS_COM_IRQHANDLER #define LUOS_COM_IRQHANDLER() USART1_IRQHandler() #endif +/******************************************************************************* + * FLASH CONFIG + ******************************************************************************/ +#ifndef LUOS_DMA_CLOCK_ENABLE +#define LUOS_DMA_CLOCK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE(); +#endif +#ifndef LUOS_DMA +#define LUOS_DMA DMA1 +#endif +#ifndef LUOS_DMA_CHANNEL +#define LUOS_DMA_CHANNEL LL_DMA_CHANNEL_4 +#endif +#ifndef LUOS_DMA_REQUEST +#define LUOS_DMA_REQUEST LL_DMA_REQUEST_2 +#endif /******************************************************************************* * COM TIMEOUT CONFIG ******************************************************************************/ diff --git a/library.json b/library.json index 04a4054..5adbe3e 100644 --- a/library.json +++ b/library.json @@ -2,7 +2,7 @@ "name": "LuosHAL", "keywords": "robus,network,microservice,luos,operating system,os,embedded,communication,module,ST", "description": "Luos Hardware Abstraction Layer", - "version": "0.2.1", + "version": "0.3.0", "authors": { "name": "Luos", "url": "https://luos.io" @@ -17,4 +17,4 @@ "type": "git", "url": "https://github.com/Luos-io/luoshal" } -} \ No newline at end of file +} diff --git a/template/luos_hal.c b/template/luos_hal.c index ba51aa6..46415ce 100644 --- a/template/luos_hal.c +++ b/template/luos_hal.c @@ -1,6 +1,6 @@ /****************************************************************************** * @file luosHAL - * @brief Luos Hardware Abstration Layer. Describe Low layer fonction + * @brief Luos Hardware Abstration Layer. Describe Low layer fonction * @MCU Family XXX * @author Luos * @version 0.0.0 @@ -17,7 +17,7 @@ /******************************************************************************* * Definitions ******************************************************************************/ -#define TIMER_RELOAD_CNT 20 +#define DEFAULT_TIMEOUT 20 /******************************************************************************* * Variables ******************************************************************************/ @@ -31,6 +31,9 @@ typedef struct } Port_t; Port_t PTP[NBR_PORT]; + +volatile uint16_t data_size_to_transmit = 0; +volatile uint8_t *tx_data = 0; /******************************************************************************* * Function ******************************************************************************/ @@ -38,12 +41,8 @@ static void LuosHAL_SystickInit(void); static void LuosHAL_FlashInit(void); static void LuosHAL_CRCInit(void); static void LuosHAL_TimeoutInit(void); -static void LuosHAL_ResetTimeout(void); -static inline void LuosHAL_ComTimeout(void); static void LuosHAL_GPIOInit(void); static void LuosHAL_FlashEraseLuosMemoryInfo(void); -static inline void LuosHAL_ComReceive(void); -static inline void LuosHAL_GPIOProcess(uint16_t GPIO); static void LuosHAL_RegisterPTP(void); /////////////////////////Luos Library Needed function/////////////////////////// @@ -102,7 +101,7 @@ static void LuosHAL_SystickInit(void) ******************************************************************************/ uint32_t LuosHAL_GetSystick(void) { - return ; //return getsystick + return ; //return tick } /****************************************************************************** * @brief Luos HAL Initialize Generale communication inter node @@ -119,6 +118,10 @@ void LuosHAL_ComInit(uint32_t Baudrate) //Enable NVIC IRQ + //enable DMA +#ifndef USE_TX_IT + //if DMA possible initialize DMA for a data transmission +#endif //Timeout Initialization Timer_Prescaler = (MCUFREQ/Baudrate)/TIMERDIV; LuosHAL_TimeoutInit(); @@ -135,7 +138,7 @@ void LuosHAL_SetTxState(uint8_t Enable) //put Tx COM pin in push pull if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) { - //Tx enable + //Tx enable } } else @@ -145,6 +148,15 @@ void LuosHAL_SetTxState(uint8_t Enable) { //Tx Disable } +#ifdef USE_TX_IT + // Stop current transmit operation + data_size_to_transmit = 0; + //Disable IT tx empty +#else + + //stop DMA transmission DMA disable +#endif + //disable tx complet IT } } /****************************************************************************** @@ -159,73 +171,96 @@ void LuosHAL_SetRxState(uint8_t Enable) //clear data register // Enable Rx com // Enable Rx IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - //Rx enable - } } else { // disable Rx com // disable Rx IT - if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) - { - //Rx Disable - } } } /****************************************************************************** - * @brief Process data receive + * @brief Process data send or receive * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComReceive(void) +void LUOS_COM_IRQHANDLER() { + // Reset timeout to it's default value LuosHAL_ResetTimeout(); - //data receive IT - - //Framming error IT -} -/****************************************************************************** - * @brief Process data transmit - * @param None - * @return None - ******************************************************************************/ -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size) -{ - for (uint16_t i = 0; i < size; i++) - { - ctx.tx.lock = true; - //ready to send - if (ctx.tx.collision) + // reception management + //if IT receive and IT receive enable + //get data from register + ctx.rx.callback(&data); // send reception byte to state machine + if (data_size_to_transmit == 0) + { + //clear error IT + return; + } + //else if Framming error IT + ctx.rx.status.rx_framing_error = true; + + // Transmission management + //if IT transmit complete and IT transmit complete enable + LuosHAL_SetRxState(true); + LuosHAL_SetTxState(false); + //diasble It tx complete + +#ifdef USE_TX_IT + //else if IT transmit empty and IT transmit empty enable + // Transmit buffer empty (this is a software DMA) + data_size_to_transmit--; + //put data to register + if (data_size_to_transmit == 0) { - // There is a collision - ctx.tx.collision = FALSE; - return 1; + // Transmission complete, stop loading data and watch for the end of transmission + // Disable Transmission empty buffer interrupt + // Enable Transmission complete interrupt } - //send data - LuosHAL_ResetTimeout(); } - //disable IT timout - return 0; +#endif + //clear error flag } /****************************************************************************** - * @brief Luos Tx communication complete + * @brief Process data transmit * @param None * @return None ******************************************************************************/ -void LuosHAL_ComTxComplete(void) +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size) { - //while tx complete - LuosHAL_ResetTimeout(); + //wait tx empty + LuosHAL_SetTxState(true); + // Reduce size by one because we send one directly + data_size_to_transmit = size - 1; + if (size > 1) + { + // Start the data buffer transmission + // **** NO DMA + //Copy the data pointer globally alowing to keep it and run the transmission. + tx_data = data; +#ifdef USE_TX_IT + //put data in register + //enable IT tx empty + //disable IT tx complete +#else + data_size_to_transmit = 0;//Reset this value avoiding to check IT TC during collision + //set up DMA transfert + //enable IT tx complete +#endif + } + else + { + // Transmit the only byte we have + //put data in register + // Enable Transmission complete interrupt because we only have one. + } } /****************************************************************************** * @brief set state of Txlock detection pin * @param None * @return Lock status ******************************************************************************/ -void LuosHAL_SetTxLockDetecState(uint8_t Enable) +void LuosHAL_SetRxDetecPin(uint8_t Enable) { if (TX_LOCK_DETECT_IRQ != DISABLE) { @@ -236,7 +271,7 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) } else { - ////clear flag + //set flag } } } @@ -248,24 +283,25 @@ void LuosHAL_SetTxLockDetecState(uint8_t Enable) uint8_t LuosHAL_GetTxLockState(void) { uint8_t result = false; - - #ifdef USART_ISR_BUSY - //busy flag - LuosHAL_ResetTimeout(); + +#ifdef USART_ISR_BUSY + //check busy flag + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); result = true; - #else +#else if ((TX_LOCK_DETECT_PIN != DISABLE) && (TX_LOCK_DETECT_PORT != DISABLE)) { - if(TX_LOCK_DETECT_IRQ == DISABLE) + //if pin low + result = true; + if (TX_LOCK_DETECT_IRQ == DISABLE) { - //result // - if(result == true) + if (result == true) { - LuosHAL_ResetTimeout(); + LuosHAL_ResetTimeout(DEFAULT_TIMEOUT); } } } - #endif +#endif return result; } /****************************************************************************** @@ -283,31 +319,29 @@ static void LuosHAL_TimeoutInit(void) //NVIC IT } /****************************************************************************** - * @brief Luos Timeout for Rx communication + * @brief Luos Timeout communication * @param None * @return None ******************************************************************************/ -static void LuosHAL_ResetTimeout(void) +void LuosHAL_ResetTimeout(uint16_t nbrbit) { - //disable timer // clear NVIC IT pending // clear IT flag //reset counter Timer //relaod value counter - //enable IT - //enable timer + //if nbrbit != 0 + //enable timer } /****************************************************************************** - * @brief Luos Timeout for Rx communication + * @brief Luos Timeout communication * @param None * @return None ******************************************************************************/ -static inline void LuosHAL_ComTimeout(void) +void LUOS_TIMER_IRQHANDLER() { - //It timeout - //clear IT - //stop timer - if (ctx.tx.lock == true) + //if It timeout + //clear IT + if ((ctx.tx.lock == true)&&(LuosHAL_GetTxLockState() == false)) { Recep_Timeout(); } @@ -324,42 +358,50 @@ static void LuosHAL_GPIOInit(void) if ((RX_EN_PIN != DISABLE) || (RX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : RxEN_Pin */ + //Configure GPIO pins : RxEN_Pin + //output + //no pull } if ((TX_EN_PIN != DISABLE) || (TX_EN_PORT != DISABLE)) { - /*Configure GPIO pins : TxEN_Pin */ + //Configure GPIO pins : TxEN_Pin + //output + //no pull } - /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ - if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) - { - if (TX_LOCK_DETECT_IRQ != DISABLE) - { - - } - - } - - /*Configure GPIO pin : TxPin */ - - - /*Configure GPIO pin : RxPin */ + //Configure GPIO pin : TxPin + //ALTERNATE function USART Tx + //open drain + //pull up + //Configure GPIO pin : RxPin + //ALTERNATE function USART Rx + //open drain + //pull up //configure PTP LuosHAL_RegisterPTP(); for (uint8_t i = 0; i < NBR_PORT; i++) /*Configure GPIO pins : PTP_Pin */ { + //IT falling + // pull down // Setup PTP lines LuosHAL_SetPTPDefaultState(i); //activate NVIC IT for PTP } - if (TX_LOCK_DETECT_IRQ != DISABLE) + /*Configure GPIO pins : TX_LOCK_DETECT_Pin */ + if ((TX_LOCK_DETECT_PIN != DISABLE) || (TX_LOCK_DETECT_PORT != DISABLE)) { - //activate NVIC IT for Tx detect + //pull up + //input + if (TX_LOCK_DETECT_IRQ != DISABLE) + { + //it falling + //NVIC enable + } + } } /****************************************************************************** @@ -398,10 +440,10 @@ static void LuosHAL_RegisterPTP(void) * @param GPIO IT line * @return None ******************************************************************************/ -static inline void LuosHAL_GPIOProcess(uint16_t GPIO) +void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) { ////Process for Tx Lock Detec - if (GPIO == TX_LOCK_DETECT_PIN) + if (GPIO_Pin == TX_LOCK_DETECT_PIN) { ctx.tx.lock = true; //clear flag @@ -410,7 +452,7 @@ static inline void LuosHAL_GPIOProcess(uint16_t GPIO) { for (uint8_t i = 0; i < NBR_PORT; i++) { - if (GPIO == PTP[i].Pin) + if (GPIO_Pin == PTP[i].Pin) { PortMng_PtpHandler(i); break; @@ -528,7 +570,7 @@ void LuosHAL_FlashWriteLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *dat // and copy it into flash - //write data + //write data /****************************************************************************** * @brief read information from page where Luos keep permanente information @@ -539,17 +581,3 @@ void LuosHAL_FlashReadLuosMemoryInfo(uint32_t addr, uint16_t size, uint8_t *data { memcpy(data, (void *)(addr), size); } - -/////////////////////////Special LuosHAL function/////////////////////////// -void PINOUT_IRQHANDLER(uint16_t GPIO_Pin) -{ - LuosHAL_GPIOProcess(GPIO_Pin); -} -void LUOS_COM_IRQHANDLER() -{ - LuosHAL_ComReceive(); -} -void LUOS_TIMER_IRQHANDLER() -{ - LuosHAL_ComTimeout(); -} diff --git a/template/luos_hal.h b/template/luos_hal.h index 38a8bab..b567558 100644 --- a/template/luos_hal.h +++ b/template/luos_hal.h @@ -1,7 +1,7 @@ /****************************************************************************** * @file luosHAL * @brief Luos Hardware Abstration Layer. Describe Low layer fonction - * @MCU Family STM32FO + * @MCU Family XXX * @author Luos * @version 0.0.0 ******************************************************************************/ @@ -15,7 +15,6 @@ * Definitions ******************************************************************************/ #define LUOS_UUID -#define MCUFREQ #define ADDRESS_ALIASES_FLASH ADDRESS_LAST_PAGE_FLASH #define ADDRESS_BOOT_FLAG_FLASH (ADDRESS_LAST_PAGE_FLASH + PAGE_SIZE) - 4 @@ -33,10 +32,10 @@ uint32_t LuosHAL_GetSystick(void); void LuosHAL_ComInit(uint32_t Baudrate); void LuosHAL_SetTxState(uint8_t Enable); void LuosHAL_SetRxState(uint8_t Enable); -uint8_t LuosHAL_ComTransmit(uint8_t *data, uint16_t size); -void LuosHAL_SetTxLockDetecState(uint8_t Enable); +void LuosHAL_ComTransmit(uint8_t *data, uint16_t size); uint8_t LuosHAL_GetTxLockState(void); -void LuosHAL_ComTxComplete(void); +void LuosHAL_SetRxDetecPin(uint8_t Enable); +void LuosHAL_ResetTimeout(uint16_t nbrbit); void LuosHAL_SetPTPDefaultState(uint8_t PTPNbr); void LuosHAL_SetPTPReverseState(uint8_t PTPNbr); void LuosHAL_PushPTP(uint8_t PTPNbr); diff --git a/template/luos_hal_config.h b/template/luos_hal_config.h index aba54e0..86cf7d5 100644 --- a/template/luos_hal_config.h +++ b/template/luos_hal_config.h @@ -3,7 +3,7 @@ * @brief This file allow you to configure LuosHAL according to your design * this is the default configuration created by Luos team for this MCU Family * Do not modify this file if you want to ovewrite change define in you project - * @MCU Family + * @MCU Family * @author Luos * @version 0.0.0 ******************************************************************************/ @@ -12,7 +12,16 @@ //include file relative to your MCU family +//If your MCU do not Have DMA for tx transmit define USE_TX_IT + #define DISABLE 0x00 + +#ifndef MCUFREQ +#define MCUFREQ //MCU frequence +#endif +#ifndef TIMERDIV +#define TIMERDIV //clock divider for timer clock chosen +#endif /******************************************************************************* * PINOUT CONFIG ******************************************************************************/ @@ -24,107 +33,121 @@ //PTP pin definition #ifndef PTPA_PIN -#define PTPA_PIN +#define PTPA_PIN #endif #ifndef PTPA_PORT -#define PTPA_PORT +#define PTPA_PORT #endif #ifndef PTPA_IRQ -#define PTPA_IRQ +#define PTPA_IRQ #endif #ifndef PTPB_PIN -#define PTPB_PIN +#define PTPB_PIN #endif #ifndef PTPB_PORT -#define PTPB_PORT +#define PTPB_PORT #endif #ifndef PTPB_IRQ -#define PTPB_IRQ +#define PTPB_IRQ #endif //COM pin definition #ifndef TX_LOCK_DETECT_PIN -#define TX_LOCK_DETECT_PIN +#define TX_LOCK_DETECT_PIN #endif #ifndef TX_LOCK_DETECT_PORT -#define TX_LOCK_DETECT_PORT +#define TX_LOCK_DETECT_PORT #endif #ifndef TX_LOCK_DETECT_IRQ -#define TX_LOCK_DETECT_IRQ +#define TX_LOCK_DETECT_IRQ #endif #ifndef RX_EN_PIN -#define RX_EN_PIN +#define RX_EN_PIN #endif #ifndef RX_EN_PORT -#define RX_EN_PORT +#define RX_EN_PORT #endif #ifndef TX_EN_PIN -#define TX_EN_PIN +#define TX_EN_PIN #endif #ifndef TX_EN_PORT -#define TX_EN_PORT +#define TX_EN_PORT #endif #ifndef COM_TX_PIN -#define COM_TX_PIN +#define COM_TX_PIN #endif #ifndef COM_TX_PORT -#define COM_TX_PORT +#define COM_TX_PORT #endif #ifndef COM_TX_AF -#define COM_TX_AF +#define COM_TX_AF #endif #ifndef COM_RX_PIN -#define COM_RX_PIN +#define COM_RX_PIN #endif #ifndef COM_RX_PORT -#define COM_RX_PORT +#define COM_RX_PORT #endif #ifndef COM_RX_AF -#define COM_RX_AF +#define COM_RX_AF #endif #ifndef PINOUT_IRQHANDLER -#define PINOUT_IRQHANDLER(PIN) +#define PINOUT_IRQHANDLER(PIN) #endif /******************************************************************************* * COM CONFIG ******************************************************************************/ -#ifndef LUOS_COM_CLOCK_ENABLE +#ifndef LUOS_COM_CLOCK_ENABLE #define LUOS_COM_CLOCK_ENABLE() do { \ - } while(0U) + } while(0U) #endif #ifndef LUOS_COM -#define LUOS_COM +#define LUOS_COM #endif #ifndef LUOS_COM_IRQ -#define LUOS_COM_IRQ +#define LUOS_COM_IRQ #endif #ifndef LUOS_COM_IRQHANDLER -#define LUOS_COM_IRQHANDLER() +#define LUOS_COM_IRQHANDLER() +#endif + /******************************************************************************* + * FLASH CONFIG + ******************************************************************************/ +#ifndef LUOS_DMA_CLOCK_ENABLE +#define LUOS_DMA_CLOCK_ENABLE() do { \ + + } while(0U) +#endif +#ifndef LUOS_DMA +#define LUOS_DMA +#endif +#ifndef LUOS_DMA_CHANNEL +#define LUOS_DMA_CHANNEL #endif /******************************************************************************* * COM TIMEOUT CONFIG ******************************************************************************/ #ifndef LUOS_TIMER_LOCK_ENABLE #define LUOS_TIMER_LOCK_ENABLE() do { \ - + } while(0U) #endif #ifndef LUOS_TIMER -#define LUOS_TIMER +#define LUOS_TIMER #endif #ifndef LUOS_TIMER_IRQ -#define LUOS_TIMER_IRQ +#define LUOS_TIMER_IRQ #endif #ifndef LUOS_TIMER_IRQHANDLER -#define LUOS_TIMER_IRQHANDLER() +#define LUOS_TIMER_IRQHANDLER() #endif /******************************************************************************* * FLASH CONFIG