//Initialize the specified channel. Reserve A and B pins (not the IO pins) //countMode X1=1, X2=2, X4=3 HRESULT QED_Initialize (int channel, int countMode) { if (channel != 0) return CLR_E_INVALID_PARAMETER; if (countMode < 1 || countMode > 3) return CLR_E_INVALID_PARAMETER; //Reserve PA0 and PA1 if (CPU_GPIO_ReservePin(0, TRUE) == false) return CLR_E_PIN_UNAVAILABLE; if (CPU_GPIO_ReservePin(1, TRUE) == false) return CLR_E_PIN_UNAVAILABLE; //Power port A (should be already done in bootstrap) and TIM2 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; //PA0 and PA1 mode alternate: 10b GPIOA->MODER &= ~(GPIO_MODER_MODER1 | GPIO_MODER_MODER0); GPIOA->MODER |= (GPIO_MODER_MODER1_1 | GPIO_MODER_MODER0_1); //Alternate function AF1 : TIM2 input for PA1 and PA0 GPIOA->AFR[0] &= ~0x000000FF; GPIOA->AFR[0] |= 0x00000011; //pull up GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR0 | GPIO_PUPDR_PUPDR1); GPIOA->PUPDR |= (GPIO_PUPDR_PUPDR0_0 | GPIO_PUPDR_PUPDR1_0); TIM2->CR2 = 0; //external clock enable TIM2->SMCR |= TIM_SMCR_ECE; //Encoder X mode count TIM2->SMCR &= ~TIM_SMCR_SMS; TIM2->SMCR |= countMode; //if (countMode == 3) // TIM2->SMCR |= TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0; //X4 //else // TIM2->SMCR |= TIM_SMCR_SMS_1; //X2 on PA0 //filter N=8 TIM2->SMCR &= ~TIM_SMCR_ETF; TIM2->SMCR |= TIM_SMCR_ETF_1 | TIM_SMCR_ETF_0; //no polarity invertion, rising edge TIM2->CCER = 0; //Count up to 32bits TIM2->ARR = 0xFFFFFFFF; for (int IOIndex = 0; IOIndex < 2; IOIndex++) { g_completion[IOIndex].InitializeForISR(&PulseCompletionHandler, (void*)IOIndex); g_pulseLength[IOIndex] = 0; g_IOStatus[IOIndex] = IOStatus_None; } //activate interrupt and enable counter CPU_INTC_ActivateInterrupt(TIM2_IRQn, STM32F4_TIM2_Interrupt, 0); TIM2->CR1 |= TIM_CR1_CEN; return S_OK; }
void HAL_UnReserveAllGpios() { for(INT32 i = CPU_GPIO_GetPinCount()-1; i >=0; i--) { CPU_GPIO_ReservePin((GPIO_PIN)i, false); } }
//Unitialize the specified channel void QED_Uninitialize (int channel) { if (channel !=0) return; GLOBAL_LOCK(irq); //disable counter and interrupt QED_SetCountEnable(0, FALSE); CPU_INTC_DeactivateInterrupt(TIM2_IRQn); //release A and B pins CPU_GPIO_ReservePin(0, FALSE); CPU_GPIO_ReservePin(1, FALSE); for (int IOIndex = 0; IOIndex < 2; IOIndex++) { //release IO pins and discard capture/compare QED_ReleaseIO(0, IOIndex); g_completion[IOIndex].Uninitialize(); } }
//Release the specified IO pin if reserved by QED_InitOutputCompare() or QED_InitInputCapture() void QED_ReleaseIO(int channel, int IOIndex) { if (channel != 0) return; if (IOIndex < 0 || IOIndex > 1) return; if (g_IOStatus[IOIndex] != IOStatus_None) { if (IOIndex == 0) { //no capture/compare selection TIM2->CCMR2 &= ~TIM_CCMR2_CC3S; //disable capture compare TIM2->CCER &= ~TIM_CCER_CC3E; } else if (IOIndex == 1) { TIM2->CCMR2 &= ~TIM_CCMR2_CC4S; TIM2->CCER &= ~TIM_CCER_CC4E; } CPU_GPIO_ReservePin(QED_GetIOPinForChannel(channel, IOIndex), FALSE); g_IOStatus[IOIndex] = IOStatus_None; g_pulseLength[IOIndex] = 0; } }
void __section("SectionForBootstrapOperations") BootstrapCode_GPIO() { /* GPIO pins connected to NOR Flash and SRAM on the MCBSTM32F400 board */ const uint8_t PortD_PinList[] = {0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13, 14, 15}; #ifdef DEBUG // PE2,3,4,5 are used for TRACECLK and TRACEDATA0-3 so don't enable them as address pins in debug builds // This limits external FLASH and SRAM to 1MB addressable space each. const uint8_t PortE_PinList[] = {0, 1, /*2, 3, 4, 5,*/ 7, 8, 9, 10, 11, 12, 13, 14, 15}; #else const uint8_t PortE_PinList[] = {0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15}; #endif const uint8_t PortF_PinList[] = {0, 1, 2, 3, 4, 5, 12, 13, 14, 15}; const uint8_t PortG_PinList[] = {0, 1, 2, 3, 4, 5, 10}; const uint32_t pinConfig = 0x3C2; // Speed 100Mhz, AF12 FSMC, Alternate Mode const uint32_t pinMode = pinConfig & 0xF; const GPIO_ALT_MODE alternateMode = (GPIO_ALT_MODE) pinConfig; const GPIO_RESISTOR resistorConfig = RESISTOR_PULLUP; uint32_t i; /* Enable GPIO clocks */ RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN | RCC_AHB1ENR_GPIOIEN; CPU_GPIO_EnableOutputPin(LED1, FALSE); CPU_GPIO_EnableOutputPin(LED2, FALSE); CPU_GPIO_EnableOutputPin(LED3, FALSE); CPU_GPIO_EnableOutputPin(LED4, FALSE); CPU_GPIO_EnableOutputPin(LED5, FALSE); CPU_GPIO_EnableOutputPin(LED6, FALSE); CPU_GPIO_EnableOutputPin(LED7, FALSE); CPU_GPIO_EnableOutputPin(LED8, FALSE); /*Initialize SRAM and NOR GPIOs */ for(i = 0; i < ARRAY_LENGTH(PortD_PinList); i++) /* Port D */ { CPU_GPIO_ReservePin( PORT_PIN(GPIO_PORTD, PortD_PinList[i]), TRUE); CPU_GPIO_DisablePin( PORT_PIN(GPIO_PORTD, PortD_PinList[i]), resistorConfig, 0, alternateMode); STM32F4_GPIO_Pin_Config( PORT_PIN(GPIO_PORTD, PortD_PinList[i]), pinMode, resistorConfig, pinConfig ); // Workaround, since CPU_GPIO_DisablePin() does not correctly initialize pin speeds } for(i = 0; i < ARRAY_LENGTH(PortE_PinList); i++) /* Port E */ { CPU_GPIO_ReservePin( PORT_PIN(GPIO_PORTE, PortE_PinList[i]), TRUE); CPU_GPIO_DisablePin( PORT_PIN(GPIO_PORTE, PortE_PinList[i]), resistorConfig, 0, alternateMode); STM32F4_GPIO_Pin_Config( PORT_PIN(GPIO_PORTE, PortE_PinList[i]), pinMode, resistorConfig, pinConfig ); // Workaround, since CPU_GPIO_DisablePin() does not correctly initialize pin speeds } for(i = 0; i < ARRAY_LENGTH(PortF_PinList); i++) /* Port F */ { CPU_GPIO_ReservePin( PORT_PIN(GPIO_PORTF, PortF_PinList[i]), TRUE); CPU_GPIO_DisablePin( PORT_PIN(GPIO_PORTF, PortF_PinList[i]), resistorConfig, 0, alternateMode); STM32F4_GPIO_Pin_Config( PORT_PIN(GPIO_PORTF, PortF_PinList[i]), pinMode, resistorConfig, pinConfig ); // Workaround, since CPU_GPIO_DisablePin() does not correctly initialize pin speeds } for(i = 0; i < ARRAY_LENGTH(PortG_PinList); i++) /* Port G */ { CPU_GPIO_ReservePin( PORT_PIN(GPIO_PORTG, PortG_PinList[i]), TRUE); CPU_GPIO_DisablePin( PORT_PIN(GPIO_PORTG, PortG_PinList[i]), resistorConfig, 0, alternateMode); STM32F4_GPIO_Pin_Config( PORT_PIN(GPIO_PORTG, PortG_PinList[i]), pinMode, resistorConfig, pinConfig ); // Workaround, since CPU_GPIO_DisablePin() does not correctly initialize pin speeds } /* Initialize NOR and SRAM */ InitNorFlash(); InitSram(); }
//Initialize the specified IO for input capture on raising edge or falling edge if invert is true //Reserve the IO pin at first call HRESULT QED_InitInputCapture(int channel, int IOIndex, BOOL invert, QED_EVENT onInputCapture) { if (channel != 0) return CLR_E_INVALID_PARAMETER; if (IOIndex < 0 || IOIndex > 1) return CLR_E_INVALID_PARAMETER; if (g_IOStatus[IOIndex] == IOStatus_OutputCompare) return CLR_E_PIN_UNAVAILABLE; if (g_IOStatus[IOIndex] == IOStatus_None) { if (CPU_GPIO_ReservePin(QED_GetIOPinForChannel(channel, IOIndex), TRUE) == false) return CLR_E_PIN_UNAVAILABLE; g_IOStatus[IOIndex] = IOStatus_InputCapture; } if (IOIndex == 0) { //disable capture/compare TIM2->CCER &= ~TIM_CCER_CC3E; //PA2 mode alternate: 10b GPIOA->MODER &= ~GPIO_MODER_MODER2; GPIOA->MODER |= GPIO_MODER_MODER2_1; //Alternate function AF1 : TIM2 CH3 for PA2 GPIOA->AFR[0] &= ~0x00000F00; GPIOA->AFR[0] |= 0x00000100; //pull up GPIOA->PUPDR &= ~ GPIO_PUPDR_PUPDR2; GPIOA->PUPDR |= GPIO_PUPDR_PUPDR2_0; //capture on ch3 TIM2->CCMR2 &= ~TIM_CCMR2_CC3S; TIM2->CCMR2 |= TIM_CCMR2_CC3S_0; //input filter N=8 TIM2->CCMR2 &= ~TIM_CCMR2_IC3F; TIM2->CCMR2 |= TIM_CCMR2_IC3F_1 | TIM_CCMR2_IC3F_0; //no prescaler TIM2->CCMR2 &= ~TIM_CCMR2_IC3PSC; //non inverting/rising edge TIM2->CCER &= ~TIM_CCER_CC3NP; if (invert) { //inverting/falling edge TIM2->CCER &= ~TIM_CCER_CC3P; } else { //non inverting/rising edge TIM2->CCER &= ~TIM_CCER_CC3P; } //no DMA TIM2->DIER &= ~TIM_DIER_CC3DE; //enabled TIM2->CCER |= TIM_CCER_CC3E; } else if (IOIndex == 1) { //disable capture/compare TIM2->CCER &= ~TIM_CCER_CC4E; //PA3 mode alternate: 10b GPIOA->MODER &= ~GPIO_MODER_MODER3; GPIOA->MODER |= GPIO_MODER_MODER3_1; //Alternate function AF1 : TIM2 CH4 for PA3 GPIOA->AFR[0] &= ~0x0000F000; GPIOA->AFR[0] |= 0x00001000; //pull up GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR3; GPIOA->PUPDR |= GPIO_PUPDR_PUPDR3_0; //capture on ch4 pins TIM2->CCMR2 &= ~TIM_CCMR2_CC4S; TIM2->CCMR2 |= TIM_CCMR2_CC4S_0; //input filter N=8 TIM2->CCMR2 &= ~TIM_CCMR2_IC4F; TIM2->CCMR2 |= TIM_CCMR2_IC4F_1 | TIM_CCMR2_IC4F_0; //no prescaler TIM2->CCMR2 &= ~TIM_CCMR2_IC4PSC; //polarity TIM2->CCER &= ~TIM_CCER_CC4NP; if (invert) { //inverting/falling edge TIM2->CCER &= ~TIM_CCER_CC4P; } else { //non inverting/rising edge TIM2->CCER &= ~TIM_CCER_CC4P; } //no DMA TIM2->DIER &= ~TIM_DIER_CC4DE; //capture enabled TIM2->CCER |= TIM_CCER_CC4E; } g_pulseLength[IOIndex] = 0; g_eventCallback[IOIndex] = onInputCapture; return S_OK; }
//Initialize the specified IO for output compare, negative pulse if invert is true //pulseLength=0 means infinite pulse //Reserve the IO pin and set the output state at first call, support successive calls (do not set the output state if not first call) HRESULT QED_InitOutputCompare(int channel, int IOIndex, int value, BOOL invert, int pulseLength, QED_EVENT onOutputCompare) { if (channel != 0) return CLR_E_INVALID_PARAMETER; if (IOIndex < 0 || IOIndex > 1) return CLR_E_INVALID_PARAMETER; if (g_IOStatus[IOIndex] == IOStatus_InputCapture) return CLR_E_PIN_UNAVAILABLE; if (g_IOStatus[IOIndex] == IOStatus_None) { GPIO_PIN IOPin = QED_GetIOPinForChannel(channel, IOIndex); if (CPU_GPIO_ReservePin(IOPin, TRUE) == false) return CLR_E_PIN_UNAVAILABLE; g_IOStatus[IOIndex] = IOStatus_OutputCompare; } if (IOIndex == 0) { //disable capture/compare TIM2->CCER &= ~TIM_CCER_CC3E; //PA3 mode alternate: 10b GPIOA->MODER &= ~GPIO_MODER_MODER2; GPIOA->MODER |= GPIO_MODER_MODER2_1; //Alternate function AF1 : TIM2 CH3 for PA2 GPIOA->AFR[0] &= ~0x00000F00; GPIOA->AFR[0] |= 0x00000100; //set compare on ch3 TIM2->CCMR2 &= ~TIM_CCMR2_CC3S; //set output on match TIM2->CCMR2 &= ~TIM_CCMR2_OC3M; TIM2->CCMR2 |= TIM_CCMR2_OC3M_0; //polarity if (invert) TIM2->CCER |= TIM_CCER_CC3P; else TIM2->CCER &= ~TIM_CCER_CC3P; //init comparison value TIM2->CCR3 = value; //enable output TIM2->CCER |= TIM_CCER_CC3E; //enable interrupt, no DMA TIM2->DIER |= TIM_DIER_CC3IE; TIM2->DIER &= ~TIM_DIER_CC3DE; } else if (IOIndex == 1) { //disable capture/compare TIM2->CCER &= ~TIM_CCER_CC4E; //PA3 mode alternate: 10b GPIOA->MODER &= ~GPIO_MODER_MODER3; GPIOA->MODER |= GPIO_MODER_MODER3_1; //Alternate function AF1 : TIM2 CH4 for PA3 GPIOA->AFR[0] &= ~0x0000F000; GPIOA->AFR[0] |= 0x00001000; //set compare on ch4 TIM2->CCMR2 &= ~TIM_CCMR2_CC4S; //set output on match TIM2->CCMR2 &= ~TIM_CCMR2_OC4M; TIM2->CCMR2 |= TIM_CCMR2_OC4M_0; //polarity if (invert) TIM2->CCER |= TIM_CCER_CC4P; else TIM2->CCER &= ~TIM_CCER_CC4P; //init comparison value TIM2->CCR4 = value; //enable output TIM2->CCER |= TIM_CCER_CC4E; //enable interrupt, no DMA TIM2->DIER |= TIM_DIER_CC4IE; TIM2->DIER &= ~TIM_DIER_CC4DE; } //init output state at first call or if precedent setting was infinite pulse length if (g_pulseLength[IOIndex] == 0) QED_ResetOutput(IOIndex); g_pulseLength[IOIndex] = pulseLength; g_eventCallback[IOIndex] = onOutputCompare; return S_OK; }
BOOL SD_BS_Driver::ChipInitialize(void *context) { SD_BLOCK_CONFIG *config = (SD_BLOCK_CONFIG*)context; if(!config || !config->BlockDeviceInformation) { return FALSE; } BlockDeviceInfo *pDevInfo = config->BlockDeviceInformation; UINT32 alternate = 0x1C2; CPU_GPIO_DisablePin(PC8_SD_D0, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate); CPU_GPIO_DisablePin(PC9_SD_D1, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate); CPU_GPIO_DisablePin(PC10_SD_D2, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate); CPU_GPIO_DisablePin(PC11_SD_D3, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate); CPU_GPIO_DisablePin(PC12_SD_CLK, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)alternate); CPU_GPIO_DisablePin(PD2_SD_CMD, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)alternate); CPU_GPIO_ReservePin( PC8_SD_D0, TRUE ); CPU_GPIO_ReservePin( PC9_SD_D1, TRUE ); CPU_GPIO_ReservePin( PC10_SD_D2, TRUE ); CPU_GPIO_ReservePin( PC11_SD_D3, TRUE ); CPU_GPIO_ReservePin( PC12_SD_CLK, TRUE ); CPU_GPIO_ReservePin( PD2_SD_CMD, TRUE ); RCC->APB2ENR |= (1 << 11); CPU_INTC_ActivateInterrupt( /*UINT32 Irq_Index*/SDIO_IRQn, /*HAL_CALLBACK_FPN ISR*/SDIO_IRQHandler, /*void* ISR_Param*/0 ); __IO SD_Error errorstatus = SD_OK; //errorstatus = SD_PowerON(); errorstatus = SD_Init(); CPU_INTC_InterruptEnable( /*UINT32 Irq_Index*/SDIO_IRQn ); memset(pBuffer, 0xFF, 512); errorstatus = SD_ReadBlock(pBuffer, 0, 512); //errorstatus = SD_WaitReadOperation(); //while(SD_GetStatus() != SD_TRANSFER_OK); if (SD_GetStatus() != SD_TRANSFER_OK) { if (SD_GetStatus_WithTimeOut(SD_INITIALIZE_TIMEOUT)== FALSE) return FALSE; } //CPU_FlushCaches(); // // Variables to setup SD Card Dynamically. // //BYTE regCSD[16]; <-- Not used because we have better register access. BYTE C_SIZE_MULT = 0; BYTE TAAC, NSAC, MAX_RAN_SPEED, READ_BL_LEN, SECTOR_SIZE; BOOL ERASE_BL_EN; UINT32 C_SIZE; UINT64 MemCapacity = 0; //total memory size, in unit of byte TAAC = SDCardInfo.SD_csd.TAAC; // regCSD[1]; /* STM // Original */ NSAC = SDCardInfo.SD_csd.NSAC; // regCSD[2]; /* STM // Original */ MAX_RAN_SPEED = SDCardInfo.SD_csd.MaxBusClkFrec; // regCSD[3]; /* STM // Original */ READ_BL_LEN = SDCardInfo.SD_csd.RdBlockLen; // regCSD[5] &0x0F; /* STM // Original */ // Checks to see if the SD card is Version 1.0: Standard or Version 2.0: High Capacity if(SDCardInfo.SD_csd.CSDStruct == 0x00) /*if(regCSD[0] == 0x00)*/ // SD Version1.0 { C_SIZE = SDCardInfo.SD_csd.DeviceSize; // ((regCSD[6] &0x3) << 10) | (regCSD[7] << 2) | ((regCSD[8] &0xC0) >> 6); /* STM // Original */ C_SIZE_MULT = SDCardInfo.SD_csd.DeviceSizeMul; // ((regCSD[9] &0x03) << 1) | ((regCSD[10] &0x80) >> 7); /* STM // Original */ ERASE_BL_EN = (SDCardInfo.SD_csd.EraseGrSize == 0x00) ? FALSE : TRUE; // ((regCSD[10] &0x40) == 0x00) ? FALSE : TRUE; /* STM // Original */ SECTOR_SIZE = SDCardInfo.SD_csd.EraseGrMul; // ((regCSD[10] &0x3F) << 1) | ((regCSD[11] &0x80) >> 7); /* STM // Original */ MemCapacity = SDCardInfo.CardCapacity; // (C_SIZE + 1) * (0x1 << (C_SIZE_MULT + 2)) * (0x1 << READ_BL_LEN); /* STM // Original */ IsSDCardHC = FALSE; } else // SD Version2.0 { C_SIZE = SDCardInfo.SD_csd.DeviceSize; // ((regCSD[7] &0x3F) << 16) | (regCSD[8] << 8) | regCSD[9]; /* STM // Original */ ERASE_BL_EN = (SDCardInfo.SD_csd.EraseGrSize == 0x00) ? FALSE : TRUE; // ((regCSD[10] &0x40) == 0x00) ? FALSE : TRUE; /* STM // Original */ SECTOR_SIZE = SDCardInfo.SD_csd.EraseGrMul; // ((regCSD[10] &0x3F) << 1) | ((regCSD[11] &0x80) >> 7); /* STM // Original */ MemCapacity = SDCardInfo.CardCapacity; // (C_SIZE + 1) * 512 * 1024; /* STM // Original */ IsSDCardHC = TRUE; } //Update SD config according to CSD register UINT32 SectorsPerBlock = (ERASE_BL_EN == TRUE) ? 1 : (SECTOR_SIZE + 1); pDevInfo->BytesPerSector = 512; // data bytes per sector is always 512 pDevInfo->Size = (ByteAddress)MemCapacity; BlockRegionInfo* pRegions = (BlockRegionInfo*)&pDevInfo->Regions[0]; pRegions[0].BytesPerBlock = SectorsPerBlock * pDevInfo->BytesPerSector; pRegions[0].NumBlocks = (UINT32)(MemCapacity / pRegions[0].BytesPerBlock); BlockRange* pRanges = (BlockRange*)&pRegions[0].BlockRanges[0]; pRanges[0].StartBlock = 0; pRanges[0].EndBlock = pRegions[0].NumBlocks-1; return TRUE; }