/** * @brief Configures the SMARTCARD peripheral. * @param hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for the specified SMARTCARD module. * @retval None */ static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) { /* Check the parameters */ assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity)); assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase)); assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit)); assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate)); assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength)); assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits)); assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity)); assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode)); assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState)); /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */ CLEAR_BIT(hsc->Instance->CR1, (uint32_t)(USART_CR1_TE | USART_CR1_RE)); /*-------------------------- SMARTCARD CR2 Configuration ------------------------*/ /* Clear CLKEN, CPOL, CPHA and LBCL bits */ /* Configure the SMARTCARD Clock, CPOL, CPHA and LastBit -----------------------*/ /* Set CPOL bit according to hsc->Init.CLKPolarity value */ /* Set CPHA bit according to hsc->Init.CLKPhase value */ /* Set LBCL bit according to hsc->Init.CLKLastBit value */ MODIFY_REG(hsc->Instance->CR2, ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL)), ((uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity | hsc->Init.CLKPhase| hsc->Init.CLKLastBit)) ); /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */ MODIFY_REG(hsc->Instance->CR2, USART_CR2_STOP,(uint32_t)(hsc->Init.StopBits)); /*-------------------------- SMARTCARD CR1 Configuration -----------------------*/ /* Clear M, PCE, PS, TE and RE bits */ /* Configure the SMARTCARD Word Length, Parity and mode: Set the M bits according to hsc->Init.WordLength value Set PCE and PS bits according to hsc->Init.Parity value Set TE and RE bits according to hsc->Init.Mode value */ MODIFY_REG(hsc->Instance->CR1, ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE)), ((uint32_t)(hsc->Init.WordLength | hsc->Init.Parity | hsc->Init.Mode)) ); /*-------------------------- USART CR3 Configuration -----------------------*/ /* Clear CTSE and RTSE bits */ CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE)); /*-------------------------- USART BRR Configuration -----------------------*/ if(hsc->Instance == USART1) { hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK2Freq(), hsc->Init.BaudRate); } else { hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK1Freq(), hsc->Init.BaudRate); } }
/** * @brief Configure the SMARTCARD associated USART peripheral * @param hsc: SMARTCARD handle * @retval None */ static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) { uint32_t tmpreg = 0x00000000; uint32_t clocksource = 0x00000000; /* Check the parameters */ assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate)); assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength)); assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits)); assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity)); assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode)); assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity)); assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase)); assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit)); assert_param(IS_SMARTCARD_ONE_BIT_SAMPLE(hsc->Init.OneBitSampling)); assert_param(IS_SMARTCARD_NACK(hsc->Init.NACKState)); assert_param(IS_SMARTCARD_TIMEOUT(hsc->Init.TimeOutEnable)); assert_param(IS_SMARTCARD_AUTORETRY_COUNT(hsc->Init.AutoRetryCount)); /*-------------------------- USART CR1 Configuration -----------------------*/ /* In SmartCard mode, M and PCE are forced to 1 (8 bits + parity). * Oversampling is forced to 16 (OVER8 = 0). * Configure the Parity and Mode: * set PS bit according to hsc->Init.Parity value * set TE and RE bits according to hsc->Init.Mode value */ tmpreg = (uint32_t) hsc->Init.Parity | hsc->Init.Mode; /* in case of TX-only mode, if NACK is enabled, the USART must be able to monitor the bidirectional line to detect a NACK signal in case of parity error. Therefore, the receiver block must be enabled as well (RE bit must be set). */ if((hsc->Init.Mode == SMARTCARD_MODE_TX) && (hsc->Init.NACKState == SMARTCARD_NACK_ENABLE)) { tmpreg |= USART_CR1_RE; } tmpreg |= (uint32_t) hsc->Init.WordLength; MODIFY_REG(hsc->Instance->CR1, USART_CR1_FIELDS, tmpreg); /*-------------------------- USART CR2 Configuration -----------------------*/ /* Stop bits are forced to 1.5 (STOP = 11) */ tmpreg = hsc->Init.StopBits; /* Synchronous mode is activated by default */ tmpreg |= (uint32_t) USART_CR2_CLKEN | hsc->Init.CLKPolarity; tmpreg |= (uint32_t) hsc->Init.CLKPhase | hsc->Init.CLKLastBit; tmpreg |= (uint32_t) hsc->Init.TimeOutEnable; MODIFY_REG(hsc->Instance->CR2, USART_CR2_FIELDS, tmpreg); /*-------------------------- USART CR3 Configuration -----------------------*/ /* Configure * - one-bit sampling method versus three samples' majority rule * according to hsc->Init.OneBitSampling * - NACK transmission in case of parity error according * to hsc->Init.NACKEnable * - autoretry counter according to hsc->Init.AutoRetryCount */ tmpreg = (uint32_t) hsc->Init.OneBitSampling | hsc->Init.NACKState; tmpreg |= (uint32_t) (hsc->Init.AutoRetryCount << SMARTCARD_CR3_SCARCNT_LSB_POS); MODIFY_REG(hsc->Instance-> CR3,USART_CR3_FIELDS, tmpreg); /*-------------------------- USART GTPR Configuration ----------------------*/ tmpreg = (uint32_t) (hsc->Init.Prescaler | (hsc->Init.GuardTime << SMARTCARD_GTPR_GT_LSB_POS)); MODIFY_REG(hsc->Instance->GTPR, (uint32_t)(USART_GTPR_GT|USART_GTPR_PSC), tmpreg); /*-------------------------- USART RTOR Configuration ----------------------*/ tmpreg = (uint32_t) (hsc->Init.BlockLength << SMARTCARD_RTOR_BLEN_LSB_POS); if(hsc->Init.TimeOutEnable == SMARTCARD_TIMEOUT_ENABLE) { assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsc->Init.TimeOutValue)); tmpreg |= (uint32_t) hsc->Init.TimeOutValue; } MODIFY_REG(hsc->Instance->RTOR, (USART_RTOR_RTO|USART_RTOR_BLEN), tmpreg); /*-------------------------- USART BRR Configuration -----------------------*/ SMARTCARD_GETCLOCKSOURCE(hsc, clocksource); switch (clocksource) { case SMARTCARD_CLOCKSOURCE_PCLK1: hsc->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK1Freq() / hsc->Init.BaudRate); break; case SMARTCARD_CLOCKSOURCE_PCLK2: hsc->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK2Freq() / hsc->Init.BaudRate); break; case SMARTCARD_CLOCKSOURCE_HSI: hsc->Instance->BRR = (uint16_t)(HSI_VALUE / hsc->Init.BaudRate); break; case SMARTCARD_CLOCKSOURCE_SYSCLK: hsc->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / hsc->Init.BaudRate); break; case SMARTCARD_CLOCKSOURCE_LSE: hsc->Instance->BRR = (uint16_t)(LSE_VALUE / hsc->Init.BaudRate); break; default: break; } }
/** * @brief Initializes the SmartCard mode according to the specified * parameters in the SMARTCARD_HandleTypeDef and create the associated handle. * @param hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for the specified SMARTCARD module. * @retval HAL status */ HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc) { /* Check the SMARTCARD handle allocation */ if(hsc == NULL) { return HAL_ERROR; } /* Check Wordlength, Parity and Stop bits parameters */ if ( (!(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength))) ||(!(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits))) ||(!(IS_SMARTCARD_PARITY(hsc->Init.Parity))) ) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState)); assert_param(IS_SMARTCARD_PRESCALER(hsc->Init.Prescaler)); if(hsc->State == HAL_SMARTCARD_STATE_RESET) { /* Allocate lock resource and initialize it */ hsc->Lock = HAL_UNLOCKED; /* Init the low level hardware */ HAL_SMARTCARD_MspInit(hsc); } hsc->State = HAL_SMARTCARD_STATE_BUSY; /* Disable the Peripheral */ __HAL_SMARTCARD_DISABLE(hsc); /* Set the Prescaler */ MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_PSC, hsc->Init.Prescaler); /* Set the Guard Time */ MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime)<<8)); /* Set the Smartcard Communication parameters */ SMARTCARD_SetConfig(hsc); /* In SmartCard mode, the following bits must be kept cleared: - LINEN bit in the USART_CR2 register - HDSEL and IREN bits in the USART_CR3 register.*/ CLEAR_BIT(hsc->Instance->CR2, USART_CR2_LINEN); CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_IREN | USART_CR3_HDSEL)); /* Enable the Peripharal */ __HAL_SMARTCARD_ENABLE(hsc); /* Configure the Smartcard NACK state */ MODIFY_REG(hsc->Instance->CR3, USART_CR3_NACK, hsc->Init.NACKState); /* Enable the SC mode by setting the SCEN bit in the CR3 register */ SET_BIT(hsc->Instance->CR3, USART_CR3_SCEN); /* Initialize the SMARTCARD state*/ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; hsc->State= HAL_SMARTCARD_STATE_READY; return HAL_OK; }