static void TM_LCD_INT_InitPins(void) {
#if defined(LCD_USE_STM32F7_DISCOVERY)
	/* Init GPIO pins for LTDC */
	TM_GPIO_InitAlternate(GPIOE, GPIO_PIN_4, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOG, GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOI, GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOJ, GPIO_PIN_All & ~(GPIO_PIN_12), TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOK, 0x00FF & ~(GPIO_PIN_3), TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast, GPIO_AF14_LTDC);
	
	/* Init pins for LCD control */
	/* Display enable */
	TM_GPIO_Init(GPIOI, GPIO_PIN_12, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_DOWN, TM_GPIO_Speed_Low);
	/* Backlight control */
	TM_GPIO_Init(GPIOK, GPIO_PIN_3, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_DOWN, TM_GPIO_Speed_Low);
#elif defined(LCD_USE_STM32F439_EVAL)
	/* LCD pins */
	TM_GPIO_InitAlternate(GPIOI, 0xF000, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast, 0x0E);
	TM_GPIO_InitAlternate(GPIOJ, 0xFFFF, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast, 0x0E);
	TM_GPIO_InitAlternate(GPIOK, 0x00FF, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast, 0x0E);	
#elif defined(LCD_USE_STM32F429_DISCOVERY)
	TM_GPIO_Init(ILI9341_WRX_PORT, ILI9341_WRX_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Medium);
	TM_GPIO_Init(ILI9341_CS_PORT, ILI9341_CS_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Medium);
	TM_GPIO_InitAlternate(GPIOA, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_11 | GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOB, GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOB, GPIO_PIN_0 | GPIO_PIN_1, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF9_LTDC);
	TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_10, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOD, GPIO_PIN_3 | GPIO_PIN_6, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOF, GPIO_PIN_10, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOG, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_11, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF14_LTDC);
	TM_GPIO_InitAlternate(GPIOG, GPIO_PIN_10 | GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF9_LTDC);
#endif
}
uint8_t TM_HCSR04_Init(TM_HCSR04_t* HCSR04, GPIO_TypeDef* ECHO_GPIOx, uint16_t ECHO_GPIO_Pin, GPIO_TypeDef* TRIGGER_GPIOx, uint16_t TRIGGER_GPIO_Pin) {	
	/* Init Delay functions */
	TM_DELAY_Init();
	
	/* Save everything */
	HCSR04->ECHO_GPIOx = ECHO_GPIOx;
	HCSR04->ECHO_GPIO_Pin = ECHO_GPIO_Pin;
	HCSR04->TRIGGER_GPIOx = TRIGGER_GPIOx;
	HCSR04->TRIGGER_GPIO_Pin = TRIGGER_GPIO_Pin;
	
	/* Initialize pins */	
	/* Trigger pin */
	TM_GPIO_Init(HCSR04->TRIGGER_GPIOx, HCSR04->TRIGGER_GPIO_Pin, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_DOWN, TM_GPIO_Speed_Medium);
	
	/* Echo pin */
	TM_GPIO_Init(HCSR04->ECHO_GPIOx, HCSR04->ECHO_GPIO_Pin, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_DOWN, TM_GPIO_Speed_Medium);
	
	/* Trigger set to low */
	TM_GPIO_SetPinLow(HCSR04->TRIGGER_GPIOx, HCSR04->TRIGGER_GPIO_Pin);
	
	/* Start measurement, check if sensor is working */
	if (TM_HCSR04_Read(HCSR04) >= 0) {
		/* Sensor OK */
		return 1;
	}
	
	/* Sensor error */
	return 0;
}
Example #3
0
int main(void)
{
  SystemInit();						// initialize MCU clocks and registers
  TM_DELAY_Init();					// initialize Delay library
  TM_DELAY_SetTime(0);				// Reset couter for systime
  Laser_GPIO_Conf();				// configure GPIO for laser control (to be able to enable/disable lasers via software
  TM_BKPSRAM_Init();				// initialize BKP RAM access library
  Laser_Update();			// load laser statuses saved in BKP RAM
  TM_USART_Init(OUTPUT_USART, OUTPUT_USART_PINS, OUTPUT_USART_SPEED);		// initialize UART used for collected Data output
  TM_USART_Init(MENU_USART, MENU_USART_PINS, MENU_USART_SPEED);				// initialize UART used for configuration
  TM_RTC_Init(TM_RTC_ClockSource_External);									// initialize RTC library
  TM_GPIO_Init(GPIOD, GPIO_Pin_8, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low); // configure GPIO for GSM status indication (RED LED)
  TM_GPIO_Init(GPIOD, GPIO_Pin_9, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low); // configure GPIO for GSM status indication (GREEN LED)
  Laser_ADC_Init();					// initialize ADC peripherals
  Menu_Init();						// initialize CLI library
  sfpInit();						// configure GPIO for SFP modules
  gsm_Init();						// initialize GSM module


  /* configure and initialize Ethernet hardware and LwIP stack */

  ETH_BSP_Config();					// configure ETH GPIOs
  printf("Ethernet MAC and PHY configured successfully!\n");
  LwIP_Init();						// start LwIP stack
  printf("LwIP stack initialized successfully!\n");
  UDP_Server_Init();				// start UDP Server
  printf("UDP Server initialized successfully!\n");

  //start periodic tasks

  /* GSM Status update "task" */
  GSM_Status_Update_Timer = TM_DELAY_TimerCreate(GSM_CHECK_INTERVAL, 1, 1, GSM_Status_Update_Timer_Task, NULL);
  printf("GSM status check task created!\n");
  /* Print results from remote devices "task" */
  Print_Results_Timer = TM_DELAY_TimerCreate(DATA_OUT_INTERVAL, 1, 1, Print_Results_Timer_Task, NULL);
  printf("Print collected data task created!\n");
  /* LaserLock status update "task" */
  LaserLock_Timer = TM_DELAY_TimerCreate(1000, 1, 1, LaserLock_Timer_Task, NULL);
  printf("Laser lock check task created!\n");

  while (1) {
	  /* CLI menu update */
	  Menu_Update();
      /* check if any packet received */
	  if (ETH_CheckFrameReceived())
	  {
		  /* process received ethernet packet */
		  LwIP_Pkt_Handle();
	  }
    /* handle periodic timers for LwIP */
    LwIP_Periodic_Handle(LocalTime);
    /* update laser statuses */
    Laser_Update();
    /* remove SMS messages which were read by system */
    delete_read_gsm_messages();
  }
} 
void TM_NRF24L01_InitPins(void) {
	/* Init pins */
	/* CNS pin */
	TM_GPIO_Init(NRF24L01_CSN_PORT, NRF24L01_CSN_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
	
	/* CE pin */
	TM_GPIO_Init(NRF24L01_CE_PORT, NRF24L01_CE_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
	
	/* CSN high = disable SPI */
	NRF24L01_CSN_HIGH;
	
	/* CE low = disable TX/RX */
	NRF24L01_CE_LOW;
}
Example #5
0
void TM_DAC_Init(TM_DAC_Channel_t DACx) {
	DAC_InitTypeDef DAC_InitStruct;
	uint16_t GPIO_Pin;
	
	/* Select proper GPIO pin */
	if (DACx == TM_DAC1) {
		GPIO_Pin = GPIO_PIN_4;
	} else {
		GPIO_Pin = GPIO_PIN_5;
	}
	
	/* Initialize proper GPIO pin */
	TM_GPIO_Init(GPIOA, GPIO_Pin, TM_GPIO_Mode_AN, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast);

	/* Enable DAC clock */
	RCC->APB1ENR |= RCC_APB1ENR_DACEN;
	
	/* Set DAC options */
	DAC_InitStruct.DAC_Trigger = DAC_Trigger_None;
	DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None;
	DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
	
	/* Init and enable proper DAC */
	if (DACx == TM_DAC1) {
		DAC_Init(DAC_Channel_1, &DAC_InitStruct);
		/* Enable DAC channel 1 */
		DAC->CR |= DAC_CR_EN1;
	} else {
		DAC_Init(DAC_Channel_2, &DAC_InitStruct);
		/* Enable DAC channel 2 */
		DAC->CR |= DAC_CR_EN2;
	}
}
TM_USB_Result_t TM_USB_InitFS(void) {
	/* Init DP and DM pins for USB */
	TM_GPIO_InitAlternate(GPIOA, GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF10_OTG_FS);

	/* Init ID pin */
	TM_GPIO_InitAlternate(GPIOA, GPIO_PIN_10, TM_GPIO_OType_OD, TM_GPIO_PuPd_UP, TM_GPIO_Speed_High, GPIO_AF10_OTG_FS);

#if defined(USB_FS_USE_ENABLE_PIN)
	/* Init VBUS ENABLE pin */
	TM_GPIO_Init(USB_FS_ENABLE_PORT, USB_FS_ENABLE_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_High);

	/* Disable USB output */
	TM_GPIO_SetPinValue(USB_FS_ENABLE_PORT, USB_FS_ENABLE_PIN, !USB_FS_ENABLE_STATE);
#endif

	/* Enable USB FS Clocks */
	__HAL_RCC_USB_OTG_FS_CLK_ENABLE();

	/* Set USBFS Interrupt priority */
	HAL_NVIC_SetPriority(OTG_FS_IRQn, USB_NVIC_PRIORITY, 0);

	/* Enable USBFS Interrupt */
	HAL_NVIC_EnableIRQ(OTG_FS_IRQn);

	/* Return OK */
	return TM_USB_Result_Ok;
}
Example #7
0
void LedInit(void) {
	/* Set pins as output */
	TM_GPIO_Init(LED_PORT, LED_ALL, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
	
	/* Turn leds off */
	LedOff(LED_ALL);
}
Example #8
0
void GPIO_Config()
{
    TM_GPIO_Init(GPIOF, 
            GPIO_PIN_10 | GPIO_PIN_9 | GPIO_PIN_8 | GPIO_PIN_7, 
            TM_GPIO_Mode_OUT, 
            TM_GPIO_OType_PP, 
            TM_GPIO_PuPd_NOPULL, 
            TM_GPIO_Speed_High);  
}
TM_USB_Result_t TM_USB_InitHS(void) {
#if defined(USB_USE_HS)
#if defined(USB_USE_ULPI_PHY)
	/* Use external ULPI PHY */

	/* D0 and CLK */
	TM_GPIO_InitAlternate(GPIOA, GPIO_PIN_3 | GPIO_PIN_5, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF10_OTG_HS);
	/* D1 D2 D3 D4 D5 D6 D7 */
	TM_GPIO_InitAlternate(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF10_OTG_HS);
	/* STP */
	TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_0, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF10_OTG_HS);
	/* NXT */
	TM_GPIO_InitAlternate(GPIOH, GPIO_PIN_4, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF10_OTG_HS);
	/* DIR */
#if defined(USB_USE_STM32F7_DISCOVERY)
	TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_2, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF10_OTG_HS);
#else
	TM_GPIO_InitAlternate(GPIOI, GPIO_PIN_11, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF10_OTG_HS);
#endif

	/* Enable ULPI clock */
	__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
#else
	/* Use embedded PHY */
	/* Init ID, VBUS, DP and DM pins for USB */
	TM_GPIO_InitAlternate(GPIOB, GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High, GPIO_AF12_OTG_HS_FS);

#if defined(USB_HS_USE_ENABLE_PIN)
	/* Init VBUS ENABLE pin */
	TM_GPIO_Init(USB_HS_ENABLE_PORT, USB_HS_ENABLE_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_High);

	/* Disable USB output */
	TM_GPIO_SetPinValue(USB_HS_ENABLE_PORT, USB_HS_ENABLE_PIN, !USB_HS_ENABLE_STATE);
#endif /* USB_HS_USE_ENABLE_PIN */
#endif /* USB_USE_ULPI_PHY */

	/* Enable USB HS Clocks */
	__HAL_RCC_USB_OTG_HS_CLK_ENABLE();

	/* Set USBHS Interrupt priority */
	HAL_NVIC_SetPriority(OTG_HS_IRQn, USB_NVIC_PRIORITY, 0);

	/* Enable USBHS Interrupt */
	HAL_NVIC_EnableIRQ(OTG_HS_IRQn);

	/* Return OK */
	return TM_USB_Result_Ok;
#else
	/* Return ERROR */
	return TM_USB_Result_Error;
#endif
}
TM_AM2301_Result_t TM_AM2301_Init(TM_AM2301_t* AMStruct, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
	/* Initialize delay */
	TM_DELAY_Init();
	
	/* Initialize pin */
	TM_GPIO_Init(GPIOx, GPIO_Pin, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Medium);
	
	/* Save settings */
	AMStruct->GPIOx = GPIOx;
	AMStruct->GPIO_Pin = GPIO_Pin;
	
	/* Return OK */
	return TM_AM2301_Result_Ok;
}
TM_BUTTON_t* TM_BUTTON_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint8_t ButtonState, void (*ButtonHandler)(TM_BUTTON_t*, TM_BUTTON_PressType_t)) {
	TM_BUTTON_t* ButtonStruct;
	TM_GPIO_PuPd_t P;
	
	/* Init delay function */
	TM_DELAY_Init();
	
	/* Check if available */
	if (Buttons.ButtonsCount >= BUTTON_MAX_BUTTONS) {
		return NULL;
	}
	
	/* Allocate memory for button */
	ButtonStruct = (TM_BUTTON_t *) malloc(sizeof(TM_BUTTON_t));
	
	/* Check if allocated */
	if (ButtonStruct == NULL) {
		return NULL;
	}
	
	/* Save settings */
	ButtonStruct->GPIOx = GPIOx;
	ButtonStruct->GPIO_Pin = GPIO_Pin;
	ButtonStruct->GPIO_State = ButtonState ? 1 : 0;
	ButtonStruct->ButtonHandler = ButtonHandler;
	ButtonStruct->State = BUTTON_STATE_START;
	
	/* Set default values */
	ButtonStruct->PressNormalTime = BUTTON_NORMAL_PRESS_TIME;
	ButtonStruct->PressLongTime = BUTTON_LONG_PRESS_TIME;
	ButtonStruct->PressDebounceTime = BUTTON_DEBOUNCE_TIME;
	
	/* Init pin with pull resistor */
	if (ButtonStruct->GPIO_State) {
		/* Pulldown */
		P = TM_GPIO_PuPd_DOWN;
	} else {
		/* Pullup */
		P = TM_GPIO_PuPd_UP;
	}
	
	/* Init GPIO pin as input with proper pull resistor */
	TM_GPIO_Init(GPIOx, GPIO_Pin, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, P, TM_GPIO_Speed_Low);
	
	/* Save button */
	Buttons.Buttons[Buttons.ButtonsCount++] = ButtonStruct;
	
	/* Return button pointer */
	return ButtonStruct;
}
Example #12
0
static void TM_HD44780_InitPins(void) {
	/* Init all pins */
	TM_GPIO_Init(HD44780_RS_PORT, HD44780_RS_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	TM_GPIO_Init(HD44780_E_PORT, HD44780_E_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	TM_GPIO_Init(HD44780_D4_PORT, HD44780_D4_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	TM_GPIO_Init(HD44780_D5_PORT, HD44780_D5_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	TM_GPIO_Init(HD44780_D6_PORT, HD44780_D6_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	TM_GPIO_Init(HD44780_D7_PORT, HD44780_D7_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	
	/* Set pins low */
	TM_GPIO_SetPinLow(HD44780_RS_PORT, HD44780_RS_PIN);
	TM_GPIO_SetPinLow(HD44780_E_PORT, HD44780_E_PIN);
	TM_GPIO_SetPinLow(HD44780_D4_PORT, HD44780_D4_PIN);
	TM_GPIO_SetPinLow(HD44780_D5_PORT, HD44780_D5_PIN);
	TM_GPIO_SetPinLow(HD44780_D6_PORT, HD44780_D6_PIN);
	TM_GPIO_SetPinLow(HD44780_D7_PORT, HD44780_D7_PIN);
}
Example #13
0
static void TM_HD44780_InitPins(void) {
	/* Init all pins */
	TM_GPIO_Init(HD44780_RS_PORT, HD44780_RS_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_LOW);
	TM_GPIO_Init(HD44780_E_PORT, HD44780_E_PIN, GPIO_MODE_OUTPUT_PP,  GPIO_NOPULL, GPIO_SPEED_LOW);
	TM_GPIO_Init(HD44780_D4_PORT, HD44780_D4_PIN, GPIO_MODE_OUTPUT_PP,  GPIO_NOPULL, GPIO_SPEED_LOW);
	TM_GPIO_Init(HD44780_D5_PORT, HD44780_D5_PIN, GPIO_MODE_OUTPUT_PP,  GPIO_NOPULL, GPIO_SPEED_LOW);
	TM_GPIO_Init(HD44780_D6_PORT, HD44780_D6_PIN, GPIO_MODE_OUTPUT_PP,  GPIO_NOPULL, GPIO_SPEED_LOW);
	TM_GPIO_Init(HD44780_D7_PORT, HD44780_D7_PIN, GPIO_MODE_OUTPUT_PP,  GPIO_NOPULL, GPIO_SPEED_LOW);
	
	/* Set pins low */

	HAL_GPIO_WritePin(HD44780_RS_PORT, HD44780_RS_PIN,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(HD44780_E_PORT, HD44780_E_PIN,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(HD44780_D4_PORT, HD44780_D4_PIN,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(HD44780_D5_PORT, HD44780_D5_PIN,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(HD44780_D6_PORT, HD44780_D6_PIN,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(HD44780_D7_PORT, HD44780_D7_PIN,GPIO_PIN_RESET);
}
TM_DAC_SIGNAL_Result_t TM_DAC_SIGNAL_Init(TM_DAC_SIGNAL_Channel_t DACx, TIM_TypeDef* TIMx) {
	uint16_t GPIO_Pin;
	
	/* Check used timer */
	/* Set proper trigger */
	if (
		TIMx == TIM2 || 
		TIMx == TIM4 ||
		TIMx == TIM5 ||
		TIMx == TIM6 ||
		TIMx == TIM7 ||
		TIMx == TIM8
	) {
		/* Set timer */
		DAC_TIM[DACx] = TIMx;
		/* Set flag */
		dac_timer_set[DACx] = 1;
	} else {
		/* Timer is not valid */
		return TM_DAC_SIGNAL_Result_TimerNotValid;
	}

	
	/* Select proper GPIO pin */
	if (DACx == TM_DAC1) {
		GPIO_Pin = GPIO_PIN_4;
	} else {
		GPIO_Pin = GPIO_PIN_5;
	}
	
	/* Initialize proper GPIO pin */
	TM_GPIO_Init(GPIOA, GPIO_Pin, TM_GPIO_Mode_AN, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast);
	
	/* Return OK */
	return TM_DAC_SIGNAL_Result_Ok;
}
Example #15
0
/* Private functions */
void TM_L3GD20_INT_InitPins(void) {
	/* Init CS pin for SPI */
	TM_GPIO_Init(L3GD20_CS_PORT, L3GD20_CS_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
	/* Set CS high */
	L3GD20_CS_HIGH;
}
Example #16
0
int main(void) {

    int accelData[3];
    int analogData[BUFFER];
    int i=0;
    for(i=0;i<BUFFER;i++){ analogData[i]=0;	}
    int a = 0;
    int analogIn = 0;
    int analogMin, analogMax;

    /* Initialize system */
    SystemInit();

    /* Initialize delay */
    //TM_DELAY_Init();

    /* Initialize PG13 (GREEN LED) and PG14 (RED LED) */
    TM_GPIO_Init(GPIOG, GPIO_PIN_13 | GPIO_PIN_14, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast);
    TM_GPIO_SetPinValue(GPIOG, GPIO_PIN_14, 1); // Red: ON

#ifdef ENABLE_USART
    /* Initialize USART1 at 115200 baud, TX: PA10, RX: PA9 */
    TM_USART_Init(USART1, TM_USART_PinsPack_1, 115200);
#endif

#ifdef ENABLE_VCP
    /* Initialize USB Virtual Comm Port */

    TM_USB_VCP_Result status = TM_USB_VCP_NOT_CONNECTED;
    while (TM_USB_VCP_GetStatus() != TM_USB_VCP_CONNECTED) {
    	TM_USB_VCP_Init();
    	TM_GPIO_TogglePinValue(GPIOG, GPIO_PIN_14);
    	Delay(500000);
    }
    SendString("USB VCP initialized and connected\n");
    TM_GPIO_TogglePinValue(GPIOG, GPIO_PIN_14 | GPIO_PIN_13); // Red: OFF, Gr: ON

#endif

#ifdef ENABLE_MMA

    /* Initialize MMA845X */
    uint8_t mma_status = MMA845X_Initialize(MMA_RANGE_4G);
    if (mma_status == MMA_OK) {
    	SendString("MMA initialized\n");
    } else {
    	SendString("MMA initialization failed, error code: ");
    	// Add 48 to the byte value to have character representation, (48 = '0')
    	SendChar('0'+mma_status);
    	SendChar('\n');
    }

#endif

    /* Initialize Display */
	TM_ILI9341_Init();
	TM_ILI9341_Rotate(TM_ILI9341_Orientation_Portrait_1);
	TM_ILI9341_SetLayer1();
	TM_ILI9341_Fill(ILI9341_COLOR_BLACK); /* Fill data on layer 1 */

	/* Initialize ADC1 */
	TM_ADC_Init(CURRENT_ADC, CURRENT_CH);

	/* Initialize PE2 and PE3 for digital output (Motor direction) */
    TM_GPIO_Init(GPIOE, GPIO_PIN_2 | GPIO_PIN_3, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Fast);
    // Set them to HIGH/LOW
    TM_GPIO_SetPinHigh(GPIOE, GPIO_PIN_3);
    TM_GPIO_SetPinLow(GPIOE, GPIO_PIN_2);

#ifdef ENABLE_PWM
    /* Set up PE5 (in front of PE4) for PWM (TIM9 CH1 PP2) (Motor speed control) */
    TM_PWM_TIM_t TIM9_Data;
    // Set PWM to 1kHz frequency on timer TIM4, 1 kHz = 1ms = 1000us
	TM_PWM_InitTimer(TIM9, &TIM9_Data, 1000);
	// Initialize PWM on TIM9, Channel 1 and PinsPack 2 = PE5
	TM_PWM_InitChannel(&TIM9_Data, TM_PWM_Channel_1, TM_PWM_PinsPack_2);
	// Set channel 1 value, 50% duty cycle
	TM_PWM_SetChannelPercent(&TIM9_Data, TM_PWM_Channel_1, 50);
#endif

	/* Initialize DAC channel 2, pin PA5 (Shaker control) */
	//TM_DAC_Init(TM_DAC2);
	/* Set 12bit analog value of 2047/4096 * 3.3V */
	//TM_DAC_SetValue(TM_DAC2, 4096);

#ifdef ENABLE_DAC
	// DAC PIN PA5
	/* Initialize DAC1, use TIM4 for signal generation */
	TM_DAC_SIGNAL_Init(TM_DAC2, TIM4);
	/* Output predefined triangle signal with frequency of 5kHz */
	TM_DAC_SIGNAL_SetSignal(TM_DAC2, TM_DAC_SIGNAL_Signal_Sinus, 50);
#endif

	/* MAIN LOOP */
    while (1) {

    	// Read acceleration data
#ifdef ENABLE_MMA
		MMA845X_ReadAcceleration(accelData);
#endif

		// Read analog input
		analogData[a] = TM_ADC_Read(CURRENT_ADC, CURRENT_CH);
		a++;
		if(a==BUFFER) {a=0;}

		// Analog average
		analogIn=0;
		analogMax=0;
		analogMin=4096;
		for(i=0;i<BUFFER;i++){
			if(analogData[i] > analogMax) { analogMax = analogData[i]; }
			if(analogData[i] < analogMin) { analogMin = analogData[i]; }
			analogIn+=analogData[i];
		}
		analogIn/=BUFFER;

		// Print graphs
		printGraphsLCD(accelData, analogData[a], analogIn, analogMin, analogMax);

		// Toggle Green led
		TM_GPIO_TogglePinValue(GPIOG, GPIO_PIN_13);

    }
}
Example #17
0
static void TM_ADC_INT_InitPin(GPIO_TypeDef* GPIOx, uint16_t PinX) {
	/* Enable GPIO pin */
	TM_GPIO_Init(GPIOx, PinX, TM_GPIO_Mode_AN, TM_GPIO_OType_PP, TM_GPIO_PuPd_DOWN, TM_GPIO_Speed_Medium);
}
Example #18
0
int main(void) {
		char str[100];

//		char buffer1[100];
		
//	/* Free and total space */
//	uint32_t total, free;
	
	/* Initialize system */
	SystemInit();
	
	/* Initialize delays */
	TM_DELAY_Init();
	/* Enable watchdog, 4 seconds before timeout */
	if (TM_WATCHDOG_Init(TM_WATCHDOG_Timeout_8s)) {
		/* Report to user */
		//printf("Reset occured because of Watchdog\n");
	}	
	/* Reset counter to 0 */
	TM_DELAY_SetTime(0);
	/* init DTMF*/
	TM_GPIO_Init(DTMF_BIT0_PORT, DTMF_BIT0_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	TM_GPIO_Init(DTMF_BIT1_PORT, DTMF_BIT1_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	TM_GPIO_Init(DTMF_BIT2_PORT, DTMF_BIT2_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	TM_GPIO_Init(DTMF_BIT3_PORT, DTMF_BIT3_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
	/* DTMF*/
		if (TM_EXTI_Attach(DFMF_BIT4_PORT, DTMF_BIT4_PIN, TM_EXTI_Trigger_Rising) == TM_EXTI_Result_Ok) {
		TM_USART_Puts(USART3, "khoi tao ngat DFMF_BIT4\n");
	}
	
	/*init interrup INPUT*/
		if (TM_EXTI_Attach(W1_D0_PORT, W1_D0_PIN, TM_EXTI_Trigger_Rising) == TM_EXTI_Result_Ok) {
		TM_USART_Puts(USART3, "khoi tao ngat W1_D0\n");
	}
		if (TM_EXTI_Attach(W1_D1_PORT, W1_D1_PIN, TM_EXTI_Trigger_Rising) == TM_EXTI_Result_Ok) {
		TM_USART_Puts(USART3, "khoi tao ngat W1_D1\n");
	}
		if (TM_EXTI_Attach(W2_D1_PORT, W2_D1_PIN, TM_EXTI_Trigger_Falling) == TM_EXTI_Result_Ok) {
		TM_USART_Puts(USART3, "khoi tao ngat W2_D1\n");
	}
		if (TM_EXTI_Attach(W2_D0_PORT, W2_D0_PIN, TM_EXTI_Trigger_Falling) == TM_EXTI_Result_Ok) {
		TM_USART_Puts(USART3, "khoi tao ngat W2_D0\n"); // W2D0
	}
	/*init SWADD*/
	TM_GPIO_Init(ADD_BIT0_PORT, ADD_BIT0_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Medium);	
	TM_GPIO_Init(ADD_BIT1_PORT, ADD_BIT1_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Medium);
	TM_GPIO_Init(ADD_BIT2_PORT, ADD_BIT2_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Medium);
	TM_GPIO_Init(ADD_BIT3_PORT, ADD_BIT3_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Medium);
	TM_GPIO_Init(ADD_BIT4_PORT, ADD_BIT4_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Medium);
	TM_GPIO_Init(ADD_BIT5_PORT, ADD_BIT5_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Medium);
	TM_GPIO_Init(ADD_BIT6_PORT, ADD_BIT6_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Medium);
	TM_GPIO_Init(ADD_BIT7_PORT, ADD_BIT7_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Medium);
	/* init OUTPUT*/
	TM_GPIO_Init(RELAY_DK1_PORT, RELAY_DK1_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
	TM_GPIO_Init(RELAY_DK2_PORT, RELAY_DK2_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
	TM_GPIO_Init(RELAY_DK3_PORT, RELAY_DK3_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
	TM_GPIO_Init(RELAY_DK4_PORT, RELAY_DK4_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
/* Initialize USART6 at 115200 baud, TX: PC6, RX: PC7 , COM 1 - RFID1 gan cong tac nguon*/ 
	TM_USART_Init(USART6, TM_USART_PinsPack_1, 115200);
/* Initialize USART3 at 115200 baud, TX: PD8, RX: PD9 ,	COM 2 -RFID 2 gan ethernet*/
	TM_USART_Init(USART3, TM_USART_PinsPack_3, 115200);
/* Initialize USART1 at 115200 baud, TX: PA9, RX: PA10, CONG 485 */
	TM_USART_Init(USART1, TM_USART_PinsPack_1, 9600);
	/* Initialize USART2, with custom pins */					// COM 3 extension PC
	//TM_USART_Init(USART2, TM_USART_PinsPack_Custom,9600);
	TM_USART_Init(USART2, TM_USART_PinsPack_2,9600);
	
/* int DIR 485 set = send , reset = recvice*/ 
	TM_GPIO_Init(CCU_DIR_PORT, CCU_DIR_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_High);
	TM_GPIO_SetPinHigh(CCU_DIR_PORT,CCU_DIR_PIN);
/* Init 2 custom timers */
/* Timer1 has reload value each 500ms, enabled auto reload feature and timer is enabled */
	CustomTimer1 = TM_DELAY_TimerCreate(500, 1, 1, CustomTIMER1_Task, NULL);
	/* Timer1 has reload value each 1000ms, enabled auto reload feature and timer is enabled */
	CustomTimer2 = TM_DELAY_TimerCreate(100, 1, 1, CustomTIMER2_Task, NULL);
/* Init LCD*/
		TM_GPIO_Init(HD44780_RW_PORT, HD44780_RW_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
		TM_GPIO_SetPinLow(HD44780_RW_PORT,HD44780_RW_PIN);

		read_sw_add();
		timeout = value_dip;
		memset(str,'\0',0);
    //Initialize LCD 20 cols x 4 rows
    TM_HD44780_Init(16, 4);
    //Save custom character on location 0 in LCD
    TM_HD44780_CreateChar(0, &customChar[0]);    
    //Put string to LCD
    TM_HD44780_Puts(0, 0, "STM32F407VET\n\rCreartbyR&D-TIS"); /* 0 dong 1, 1 dong 2*/
    TM_HD44780_Puts(0, 2, "Welcome");
		Delayms(1000);
		TM_HD44780_Clear();
		sprintf(str,"Timer out %d", timeout);
		TM_HD44780_Puts(0, 0,str);
		Delayms(1000);
		TM_HD44780_Clear();
		TM_HD44780_Puts(0, 0,"----TIS8 PRO----");
		//TM_USART_Puts(USART3, "Welcome2");

	/*creat by duc*/
		TM_WATCHDOG_Reset();

//		TM_USART_BufferEmpty(USART3);
//		TM_USART_BufferEmpty(USART6);
		flag_RFID2=0;	
		flag_RFID1=0;
	/*end by duc*/
	while (1) {
/*process 485*/
	if(flag_485){
	flag_485=0;
	if(LEDStatus==0) TM_USART_Puts(USART1, "/LED000>\r\n");
	if(LEDStatus==1) TM_USART_Puts(USART1, "/LED001>\r\n");
	if(LEDStatus==2) TM_USART_Puts(USART1, "/LED002>\r\n");
	}	

/* xu li W1D0 - dk1*/
	if(flag_W1D0){
		turn_on_dk1();
		//flag_W1D0=0;
	}
/* xu li W1D1 - dk2*/
	if(flag_W1D1){
		turn_on_dk2();
		//flag_W1D1=0;
	}
	//TM_WATCHDOG_Reset();
//		/*end*/


if(Process!=1)
		TM_HD44780_Puts(0, 2,"Wait for Card"); /* 0 dong 1, 1 dong 2*/
if(flag_RFID1==1)
		{	
		
		Process=1;
		IDCAR1[0]=BufferCom1[4];
		IDCAR1[1]=BufferCom1[5];
		IDCAR1[2]=BufferCom1[6];
		IDCAR1[3]=BufferCom1[7];
		IDCAR1[4]=BufferCom1[8];
		IDCAR1[5]=BufferCom1[9];
		IDCAR1[6]=BufferCom1[10];
		
		if(BufferCom1[1]==0x08)	
			{
			sprintf(UID1,"%02x %02x %02x %02x,1",IDCAR1[0],IDCAR1[1],IDCAR1[2],IDCAR1[3]);
			}
		if(BufferCom1[1]==0x0B) 
			{
			sprintf(UID1,"%02x %02x %02x %02x %02x %02x %02x,1",IDCAR1[0],IDCAR1[1],IDCAR1[2],IDCAR1[3],IDCAR1[4],IDCAR1[5],IDCAR1[6]);
			}
		TM_HD44780_Puts(0, 2,"Waiting PC..."); /* 0 dong 1, 1 dong 2*/
				if(check_vip(UID1)){
			flag_PC=1;
			flag_R11=1;
			timerdk1 =0;
			Process=0;
		}
		else{
		if(Process)TM_USART_Puts(USART2,UID1);
		}
		WaitPC(200);
		flag_RFID1=0;
		if(flag_PC)
		{
			TM_HD44780_Puts(0, 2,"Door opened.."); /* 0 dong 1, 1 dong 2*/
			flag_PC=0;
			ProcessAction();
		}
		else Process=0;
		flag_RFID1=0;
	}
if(flag_RFID2==1)
		{	
		
		Process=1;
		IDCAR2[0]=BufferCom2[4];
		IDCAR2[1]=BufferCom2[5];
		IDCAR2[2]=BufferCom2[6];
		IDCAR2[3]=BufferCom2[7];
		IDCAR2[4]=BufferCom2[8];
		IDCAR2[5]=BufferCom2[9];
		IDCAR2[6]=BufferCom2[10];
		
		if(BufferCom2[1]==0x08)	
			{
			sprintf(UID2,"%02x %02x %02x %02x ,2",IDCAR2[0],IDCAR2[1],IDCAR2[2],IDCAR2[3]);
			}
		if(BufferCom2[1]==0x0B) 
			{
			sprintf(UID2,"%02x %02x %02x %02x %02x %02x %02x ,2",IDCAR2[0],IDCAR2[1],IDCAR2[2],IDCAR2[3],IDCAR2[4],IDCAR2[5],IDCAR2[6]);
			}
		TM_HD44780_Puts(0, 2,"Waiting PC..."); /* 0 dong 1, 1 dong 2*/
			if(check_vip(UID2)){
			flag_PC=1;
			flag_R31=1;
			timerdk2 =0;
			Process=0;
		}
		else{
		if(Process)TM_USART_Puts(USART2,UID2);}
		WaitPC(200);
		flag_RFID2=0;
		if(flag_PC)
		{
			TM_HD44780_Puts(0, 2,"Door opened.."); /* 0 dong 1, 1 dong 2*/
			flag_PC=0;
			ProcessAction();
		}
		else Process=0;
		flag_RFID2=0;
	}
		
/**/
timer_dk1 = timerdk1/2;	
if (timer_dk1 >= timeout){
			turn_off_dk1();
			flag_R11 =0;
			flag_W1D0=0;
			timerdk1=0;
			timer_dk1=0;
			flag_RFID1=0;
			flag_RFID2=0;
			Process=0;
//			if(LEDStatus==0) TM_USART_Puts(USART3, "/LED000>\r\n");
		}
timer_dk2 = timerdk2/2;
if (timer_dk2 >= timeout){
			turn_off_dk2();
			//flag_R21 =0;
			flag_R31 =0;
			flag_W1D1=0;
			timerdk2=0;
			timer_dk2=0;
			//flag_RFID1=0;
			Process=0;
//			if(LEDStatus==0) TM_USART_Puts(USART3, "/LED000>\r\n");
		}
timer_dk3 = timerdk3;
if (timer_dk3 >= 1){
			turn_off_dk3();
			flag_R12 =0;
			timerdk3=0;
			timer_dk3=0;
		}
timer_dk4 = timerdk4;
if (timer_dk4 >= 1){
			turn_off_dk4();
			flag_R22 =0;
			timer_dk4=0;
			timerdk4=0;
		}


		TM_WATCHDOG_Reset();
}
}
Example #19
0
int main(void)
{
    /* complete state of the keyboard split into nibbles according to the FPGA transfer protocol */
    unsigned char nibbles[32] =
    {
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00       
    };
    
    
    /* map the pins of the DM65PIC to the columns and rows of the C65 and C64 keyboard
       a very good source of information is chapter 2.1.2 in the following document:
       http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt */
    
    struct GPIO_Mapping
    {
        GPIO_TypeDef* GPIOx;    /* STM32 GPIO port */
        uint16_t GPIO_Pin;      /* pin within the specified GPIO port */
    };
    
    const char Size_ColMapping_C65 = 9;
    struct GPIO_Mapping Columns_C65[Size_ColMapping_C65] =
    {
        GPIOE, GPIO_Pin_9,      /* C0 */
        GPIOE, GPIO_Pin_10,     /* C1 */
        GPIOE, GPIO_Pin_11,     /* C2 */
        GPIOE, GPIO_Pin_12,     /* C3 */
        GPIOE, GPIO_Pin_13,     /* C4 */
        GPIOE, GPIO_Pin_14,     /* C5 */
        GPIOE, GPIO_Pin_15,     /* C6 */
        GPIOC, GPIO_Pin_0,      /* C7 */
        GPIOC, GPIO_Pin_1       /* C8 */
    };
        
    const char Size_RowMapping_C65 = 11;
    struct GPIO_Mapping Rows_C65[Size_RowMapping_C65] =
    {
        GPIOE, GPIO_Pin_0,      /* R0 */
        GPIOE, GPIO_Pin_1,      /* R1 */
        GPIOE, GPIO_Pin_2,      /* R2 */
        GPIOE, GPIO_Pin_3,      /* R3 */
        GPIOE, GPIO_Pin_4,      /* R4 */
        GPIOE, GPIO_Pin_5,      /* R5 */
        GPIOE, GPIO_Pin_6,      /* R6 */
        GPIOE, GPIO_Pin_7,      /* R7 */
        GPIOE, GPIO_Pin_8,      /* R8 is exclusively used for the CAPS LOCK aka ASCII/DIN key */
        GPIOC, GPIO_Pin_2,      /* K1 special "row 9" used for scanning the CURSOR UP key */
        GPIOC, GPIO_Pin_3       /* K2 special "row 10" used for scanning the CURSOR LEFT key */
    };
    
    struct GPIO_Mapping Restore_C65 =
    {
        GPIOC, GPIO_Pin_15      /* RESTORE key */
    };
        
    const char Size_ColMapping_C64 = 8;
    struct GPIO_Mapping Columns_C64[Size_ColMapping_C64] =
    {
        GPIOD, GPIO_Pin_8,      /* C0 */
        GPIOD, GPIO_Pin_9,      /* C1 */
        GPIOD, GPIO_Pin_10,     /* C2 */
        GPIOD, GPIO_Pin_11,     /* C3 */
        GPIOD, GPIO_Pin_12,     /* C4 */
        GPIOD, GPIO_Pin_13,     /* C5 */
        GPIOD, GPIO_Pin_14,     /* C6 */
        GPIOD, GPIO_Pin_15      /* C7 */
    };
        
    const char Size_RowMapping_C64 = 8;
    struct GPIO_Mapping Rows_C64[Size_RowMapping_C64] =
    {
        GPIOD, GPIO_Pin_0,      /* R0 */
        GPIOD, GPIO_Pin_1,      /* R1 */
        GPIOD, GPIO_Pin_2,      /* R2 */
        GPIOD, GPIO_Pin_3,      /* R3 */
        GPIOD, GPIO_Pin_4,      /* R4 */
        GPIOD, GPIO_Pin_5,      /* R5 */
        GPIOD, GPIO_Pin_6,      /* R6 */
        GPIOD, GPIO_Pin_7       /* R7 */        
    };
    
    struct GPIO_Mapping Restore_C64 =
    {
        GPIOC, GPIO_Pin_14      /* RESTORE key */
    };    
            
    /* joystick mapping at the FPGA's JB port: GPIO => nibble-pos and bit-pos
        nbl #18 : joystick 1 : bit0=up, bit1=down, bit2=left, bit3=right
        nbl #19 : bit0=joy1 fire, bit2=capslock key status, bit3=restore key status
        nbl #20 : joystick 2 : bit0=up, bit1=down, bit2=left, bit3=right
        nbl #21 : bit0=joy2 fire, bit3=reset momentary-action switch status
    
       in C65 mode, which is the default, port #1 and #2 are swapped due to the
       way, how the DM65PIC is located in the MEGA65 body housing; this is why
       in below-mentioned table, joystick #1's left is going to nbl #20 instead of #18
    */  
    const char Size_JoyMapping = 10;    
    struct
    {
        GPIO_TypeDef* GPIOx;
        uint16_t GPIO_Pin;
        char nibble_count;
        char bit_count;
    } Joystick[Size_JoyMapping] =
    {
        GPIOC, GPIO_Pin_6,  20, 2,  /* Joystick #1 LEFT */
        GPIOC, GPIO_Pin_7,  20, 3,  /* Joystick #1 RIGHT */
        GPIOC, GPIO_Pin_4,  20, 0,  /* Joystick #1 UP */
        GPIOC, GPIO_Pin_5,  20, 1,  /* Joystick #1 DOWN */
        GPIOC, GPIO_Pin_12, 21, 0,  /* Joystick #1 BUTTON */
        
        GPIOC, GPIO_Pin_10, 18, 2,  /* Joystick #2 LEFT */
        GPIOC, GPIO_Pin_11, 18, 3,  /* Joystick #2 RIGHT */
        GPIOC, GPIO_Pin_9 , 18, 0,  /* Joystick #2 UP */
        GPIOC, GPIO_Pin_8,  18, 1,  /* Joystick #2 DOWN */
        GPIOC, GPIO_Pin_13, 19, 0   /* Joystick #2 BUTTON */
    };
    
    struct GPIO_Mapping LEDs[2] =
    {
        GPIOB, GPIO_Pin_5,          /* Power LED */
        GPIOB, GPIO_Pin_4           /* FDD LED */
    };
    
    const char ledPower = 0;
    const char ledFDD = 1;
        
    /* positions of special keys within the matrix */
    const char COL_CSR = 0;
    const char ROW_CSR_UP = 9;
    const char ROW_CSR_LEFT = 10;
    const char ROW_CAPSLOCK = 8;
    
    /* positions of special keys within the nibbles array */
    const char NIBBLE_CSR_DOWN = 1;
    const char BIT_CSR_DOWN = 3;
    const char NIBBLE_CSR_RIGHT = 0;
    const char BIT_CSR_RIGHT = 2;
    const char NIBBLE_RIGHT_SHIFT = 13;
    const char BIT_RIGHT_SHIFT = 0;
    const char NIBBLE_RESTORE = 19;
    const char BIT_RESTORE = 3;
    const char NIBBLE_CAPSLOCK = 19;
    const char BIT_CAPSLOCK = 2;
    
    int i, col, row, nibble_cnt, bit_cnt;
    int tmp_offs, tmp_nbl, tmp_bit;
        
    char FPGA_IN_PowerLed = 0;
    char FPGA_IN_FDDLed = 0;
    
    /* if ever any key of a C64 keyboard has been pressed, then DM64PIC switches into
       a dedicated C64 mode that swaps back the joystick ports to their "natural" (aka as printed on the PBC)
       order because when the DM65PIC is located in a C64 body housing, the ports are placed correctly */
    char C64_Mode = 0;
            
	/* Initialize System */
	SystemInit();
    TM_DELAY_Init();
	TM_SWO_Init();  

	TM_SWO_Printf("DM64PIC firmware running.\n");
    
    /* The matrix scan goes like this: let current flow through the columns and then find out if a key is pressed
       by checking, if the current from the column arrives at a certain row. That means, we configure
       all rows as outputs (no pullup/pulldown resistor) and all columns as inputs (pulldown resistor)
    */
    for (i = 0; i < Size_ColMapping_C65; i++)
        TM_GPIO_Init(Columns_C65[i].GPIOx, Columns_C65[i].GPIO_Pin, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);    
    for (i = 0; i < Size_RowMapping_C65; i++)
        TM_GPIO_Init(Rows_C65[i].GPIOx, Rows_C65[i].GPIO_Pin, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_DOWN, TM_GPIO_Speed_High);
    for (i = 0; i < Size_ColMapping_C64; i++)
        TM_GPIO_Init(Columns_C64[i].GPIOx, Columns_C64[i].GPIO_Pin, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);    
    for (i = 0; i < Size_RowMapping_C64; i++)
        TM_GPIO_Init(Rows_C64[i].GPIOx, Rows_C64[i].GPIO_Pin, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_DOWN, TM_GPIO_Speed_High);
        
    /* row 8 is exclusively used for CAPS LOCK (aka ASCII/DIN) and has inverse logic
      (pulled to GND when the key is pressed), so use pullup resistor */
    TM_GPIO_Init(Rows_C65[ROW_CAPSLOCK].GPIOx, Rows_C65[ROW_CAPSLOCK].GPIO_Pin, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_High);
    
    /* The RESTORE key is pulled to GND when pressed, so we need a pullup resistor */
    TM_GPIO_Init(Restore_C65.GPIOx, Restore_C65.GPIO_Pin, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_High);
    TM_GPIO_Init(Restore_C64.GPIOx, Restore_C64.GPIO_Pin, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_High);
        
    /* Joysticks are inverse logic, too, therefore pullup resistors are needed for the inputs */
    for (i = 0; i < Size_JoyMapping; i++)
        TM_GPIO_Init(Joystick[i].GPIOx, Joystick[i].GPIO_Pin, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_High);
    
    /* Initialze outputs for LEDs */
    TM_GPIO_Init(LEDs[ledPower].GPIOx, LEDs[ledPower].GPIO_Pin, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
    TM_GPIO_Init(LEDs[ledFDD].GPIOx, LEDs[ledFDD].GPIO_Pin, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Low);
    
    /* Initialize outputs for communicating with the FPGA via GPIO port JB for debugging    
        JB1  = PG8: clock; data must be valid before rising edge
        JB2  = PG9: start of sequence, set to 1 when the first nibble of a new 128bit sequence is presented
        JB3  = PG10: bit0 of output data nibble
        JB4  = PG11: bit1 of output data nibble
        JB7  = PG12: bit2 of output data nibble
        JB8  = PG13: bit3 of output data nibble
        JB9  = PG14: bit 0 of input bit pair
        JB10 = PG15: bit 1 of input bit pair
    */
  
    #define P_CLOCK     GPIO_Pin_8
    #define P_START     GPIO_Pin_9
    #define P_OUT_B0    GPIO_Pin_10
    #define P_OUT_B1    GPIO_Pin_11
    #define P_OUT_B2    GPIO_Pin_12
    #define P_OUT_B3    GPIO_Pin_13
    #define P_IN_B0     GPIO_Pin_14
    #define P_IN_B1     GPIO_Pin_15
       
    /* defines for debug port JA
    #define P_CLOCK     GPIO_Pin_0
    #define P_START     GPIO_Pin_1
    #define P_OUT_B0    GPIO_Pin_2
    #define P_OUT_B1    GPIO_Pin_3
    #define P_OUT_B2    GPIO_Pin_4
    #define P_OUT_B3    GPIO_Pin_5
    #define P_IN_B0     GPIO_Pin_6
    #define P_IN_B1     GPIO_Pin_7
    */
        
    /* initialize the pins for the FPGA GPIO communication */
    TM_GPIO_Init(GPIOG, P_CLOCK,  TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
    TM_GPIO_Init(GPIOG, P_START,  TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
    TM_GPIO_Init(GPIOG, P_OUT_B0, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
    TM_GPIO_Init(GPIOG, P_OUT_B1, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
    TM_GPIO_Init(GPIOG, P_OUT_B2, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
    TM_GPIO_Init(GPIOG, P_OUT_B3, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);    
    TM_GPIO_Init(GPIOG, P_IN_B0,  TM_GPIO_Mode_IN,  TM_GPIO_OType_PP, TM_GPIO_PuPd_DOWN,   TM_GPIO_Speed_High);
    TM_GPIO_Init(GPIOG, P_IN_B1,  TM_GPIO_Mode_IN,  TM_GPIO_OType_PP, TM_GPIO_PuPd_DOWN,   TM_GPIO_Speed_High);

    /* convenience defines for a better readability */
    #define FPGA_OUT(__pin, __value) TM_GPIO_SetPinValue(GPIOG, __pin, __value)
    #define FPGA_IN(__pin) TM_GPIO_GetInputPinValue(GPIOG, __pin)
    #define DM_SET_BIT(__nibblepos, __bitpos) nibbles[(__nibblepos)] = nibbles[(__nibblepos)] | (1 << (__bitpos))
    #define DM_CLR_BIT(__nibblepos, __bitpos) nibbles[(__nibblepos)] = nibbles[(__nibblepos)] & (~(1 << (__bitpos)))
        
    while(1)
    {
        /* matrix scan the keyboard */
        nibble_cnt = 0;
        bit_cnt = 0;
        for (col = 0; col < Size_ColMapping_C65; col++)
        {
            /* set all columns to LOW except the currently active one */
            for (i = 0; i < Size_ColMapping_C65; i++)
            {
                TM_GPIO_SetPinValue(Columns_C65[i].GPIOx, Columns_C65[i].GPIO_Pin, (i == col) ? 1 : 0);
                if (i < Size_ColMapping_C64)
                    TM_GPIO_SetPinValue(Columns_C64[i].GPIOx, Columns_C64[i].GPIO_Pin, (i == col) ? 1 : 0);                    
            }
                     
            /* perform standard row scanning as the MEGA65 can handle that in an untranslated (raw) way
               deliberately only scan rows 0..7 as row 8 is only for CAPS LOCK (ASCII/DIN), which needs a special treatment 
               plus: this way of doing it elegantly enables us to scan the C64 rows in parallel */            
            for (row = 0; row < 8; row++)
            {
                /* Commodore 65 */
                if (TM_GPIO_GetInputPinValue(Rows_C65[row].GPIOx, Rows_C65[row].GPIO_Pin) == 1)                    
                {
                    /* a key is pressed, so set the corresponding matrix bit */
                    DM_SET_BIT(nibble_cnt, bit_cnt);
                  	TM_SWO_Printf("C65 Key: col=%i, row=%i, nibble=%i, bit=%i.\n", col, row, nibble_cnt, bit_cnt);
                }
                
                /* Commodore 64 */
                else if (col < Size_ColMapping_C64 ? TM_GPIO_GetInputPinValue(Rows_C64[row].GPIOx, Rows_C64[row].GPIO_Pin) == 1 : 0)
                {    
                    /* detect the C64 mode */
                    if (!C64_Mode)
                    {
                        C64_Mode = 1;
                        TM_SWO_Printf("C64 mode detected. Swapping joystick ports back to normal.\n");
                        
                        for (i = 0; i < Size_JoyMapping / 2; i++)
                        {
                            tmp_offs = (Size_JoyMapping / 2) + i;
                            tmp_nbl = Joystick[i].nibble_count;
                            tmp_bit = Joystick[i].bit_count;
                            Joystick[i].nibble_count = Joystick[tmp_offs].nibble_count;
                            Joystick[i].bit_count = Joystick[tmp_offs].bit_count;
                            Joystick[tmp_offs].nibble_count = tmp_nbl;
                            Joystick[tmp_offs].bit_count = tmp_bit;
                        }
                    }
                    
                    /* a key is pressed, so set the corresponding matrix bit */
                    DM_SET_BIT(nibble_cnt, bit_cnt);
                  	TM_SWO_Printf("C64 Key: col=%i, row=%i, nibble=%i, bit=%i.\n", col, row, nibble_cnt, bit_cnt);                    
                }
                
                /* key is released, so clear the corresponding matrix bit */
                else
                    DM_CLR_BIT(nibble_cnt, bit_cnt);
                
                bit_cnt++;
                
                if (bit_cnt == 4)
                {
                    bit_cnt = 0;
                    nibble_cnt++;
                }

                Delay(1);
            }            
        }
        
        /* C65 only: handle CURSOR UP and CURSOR LEFT: to be emulated as SHIFT+CURSOR DOWN and SHIFT+CURSOR RIGHT */
        for (i = 0; i < 8; i++)
            TM_GPIO_SetPinValue(Columns_C65[i].GPIOx, Columns_C65[i].GPIO_Pin, (i == COL_CSR) ? 1 : 0);                
        if (TM_GPIO_GetInputPinValue(Rows_C65[ROW_CSR_UP].GPIOx, Rows_C65[ROW_CSR_UP].GPIO_Pin) == 1)
        {
            /* CURSOR UP */
            DM_SET_BIT(NIBBLE_CSR_DOWN, BIT_CSR_DOWN);
            DM_SET_BIT(NIBBLE_RIGHT_SHIFT, BIT_RIGHT_SHIFT);
        }
        Delay(1);
        if (TM_GPIO_GetInputPinValue(Rows_C65[ROW_CSR_LEFT].GPIOx, Rows_C65[ROW_CSR_LEFT].GPIO_Pin) == 1)
        {
            /* CURSOR LEFT */
            DM_SET_BIT(NIBBLE_CSR_RIGHT, BIT_CSR_RIGHT);
            DM_SET_BIT(NIBBLE_RIGHT_SHIFT, BIT_RIGHT_SHIFT);            
        }
        Delay(1);
        
        /* handle RESTORE key (inverse logic) */
        if ((TM_GPIO_GetInputPinValue(Restore_C65.GPIOx, Restore_C65.GPIO_Pin) == 0) ||
            (TM_GPIO_GetInputPinValue(Restore_C64.GPIOx, Restore_C64.GPIO_Pin) == 0))
            DM_SET_BIT(NIBBLE_RESTORE, BIT_RESTORE);
        else
            DM_CLR_BIT(NIBBLE_RESTORE, BIT_RESTORE);
        Delay(1);
        
        /* C65 only: handle CAPS LOCK (aka ASCII/DIN) (inverse logic) */
        if (TM_GPIO_GetInputPinValue(Rows_C65[ROW_CAPSLOCK].GPIOx, Rows_C65[ROW_CAPSLOCK].GPIO_Pin) == 0)
            DM_SET_BIT(NIBBLE_CAPSLOCK, BIT_CAPSLOCK);
        else
            DM_CLR_BIT(NIBBLE_CAPSLOCK, BIT_CAPSLOCK);
        Delay(1);
        
        /* handle joysticks */
        for (i = 0; i < Size_JoyMapping; i++)
        {
            if (TM_GPIO_GetInputPinValue(Joystick[i].GPIOx, Joystick[i].GPIO_Pin) == 0)
            {
                DM_SET_BIT(Joystick[i].nibble_count, Joystick[i].bit_count);
              	TM_SWO_Printf("Joystick: i=%i, nibble=%i, bit=%i.\n", i, Joystick[i].nibble_count, Joystick[i].bit_count);
            }
            else
                DM_CLR_BIT(Joystick[i].nibble_count, Joystick[i].bit_count);
            Delay(1);
        }
        
        /* handle the LEDs */
        TM_GPIO_SetPinValue(LEDs[ledPower].GPIOx, LEDs[ledPower].GPIO_Pin, FPGA_IN_PowerLed ? 0 : 1);
        TM_GPIO_SetPinValue(LEDs[ledFDD].GPIOx, LEDs[ledFDD].GPIO_Pin, FPGA_IN_FDDLed ? 0 : 1);
        Delay(1);
                
        /* transmit current keyboard and joystick state to FPGA and read the LED status from the FPGA */
        for (i = 0; i < 32; i++)
        {
            FPGA_OUT(P_CLOCK, 0);                                   /* clock = 0 while data is being assembled */            
            FPGA_OUT(P_START, (i == 0) ? 1 : 0);                    /* start of sequence = 1 at the very first nibble */
            
            FPGA_OUT(P_OUT_B0, (nibbles[i] & 0x01) ? 0 : 1);        /* set data lines and use inverse logic */
            FPGA_OUT(P_OUT_B1, (nibbles[i] & 0x02) ? 0 : 1);
            FPGA_OUT(P_OUT_B2, (nibbles[i] & 0x04) ? 0 : 1);
            FPGA_OUT(P_OUT_B3, (nibbles[i] & 0x08) ? 0 : 1);
                            
            Delay(1);                                               /* wait for everything to settle ... */            
            FPGA_OUT(P_CLOCK, 1);                                   /* ... then clock = 1 to trigger the FPGA to read */                                    
            Delay(1);                                               /* give the FPGA's flip/flops some time to read the data */
            
            /* read the LED status */
            if (i == 0)
            {
                FPGA_IN_PowerLed = FPGA_IN(P_IN_B0);
                FPGA_IN_FDDLed   = FPGA_IN(P_IN_B1);                
            }            
        }
    }
}
Example #20
0
void LED_ButtonInit(void) {
	/* Set pin as input */
	TM_GPIO_Init(BUTTON_PORT, BUTTON_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, BUTTON_PULL, TM_GPIO_Speed_Low);
}
Example #21
0
void init_sd_spi(void){
	TM_SPI_Init(SD_CARD_SPI, SD_CARD_SPI_PINS);
	TM_GPIO_Init(SD_CARD_CS_PORT, SD_CARD_CS_PIN, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_Medium);
	GPIO_SetBits(SD_CARD_CS_PORT, SD_CARD_CS_PIN);	//CS to high
	Delayms(10);
}
/**
  * @brief  Initializes the SD card device.
  * @param  None
  * @retval SD status
  */
uint8_t BSP_SD_Init(void) { 
	uint8_t SD_state = MSD_OK;

	/* uSD device interface configuration */
#if defined(SDIO)
	uSdHandle.Instance = SDIO;

	uSdHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
	uSdHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
	uSdHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
	uSdHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
	uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
	uSdHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV;
#elif defined(SDMMC1)
	uSdHandle.Instance = SDMMC1;

	uSdHandle.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
	uSdHandle.Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
	uSdHandle.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
	uSdHandle.Init.BusWide             = SDMMC_BUS_WIDE_1B;
	uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
	uSdHandle.Init.ClockDiv            = SDMMC_TRANSFER_CLK_DIV;	
#else
#error "NOT SUPPORTED!"
#endif

	/* Init GPIO, DMA and NVIC */
	SD_MspInit();

	/* Check if the SD card is plugged in the slot */
	if (BSP_SD_IsDetected() != SD_PRESENT) {
		return MSD_ERROR;
	}

	/* HAL SD initialization */
	if (HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK) {
		SD_state = MSD_ERROR;
	}

	/* Configure SD Bus width */
	if (SD_state == MSD_OK) {
		/* Enable wide operation */
#if defined(SDIO_BUS_WIDE_4B)
#if FATFS_SDIO_4BIT == 1
		if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK) {
#else
		if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_1B) != SD_OK) {	
#endif
#else
#if FATFS_SDIO_4BIT == 1
		if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDMMC_BUS_WIDE_4B) != SD_OK) {
#else
		if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDMMC_BUS_WIDE_1B) != SD_OK) {	
#endif
#endif
			SD_state = MSD_ERROR;
		} else {
			SD_state = MSD_OK;
		}
	}

	return  SD_state;
}

/**
 * @brief  Detects if SD card is correctly plugged in the memory slot or not.
 * @param  None
 * @retval Returns if SD is detected or not
 */
uint8_t BSP_SD_IsDetected(void) {
	return SDCARD_IsDetected();
}

/**
 * @brief  Detects if SD card is write protected
 * @param  None
 * @retval Returns if SD is write protected or not.
 */
uint8_t BSP_SD_IsWriteProtected(void) {
	return !SDCARD_IsWriteEnabled();
}

/**
  * @brief  Reads block(s) from a specified address in an SD card, in polling mode.
  * @param  pData: Pointer to the buffer that will contain the data to transmit
  * @param  ReadAddr: Address from where data is to be read  
  * @param  BlockSize: SD card data block size, that should be 512
  * @param  NumOfBlocks: Number of SD blocks to read 
  * @retval SD status
  */
uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks) {
	if (HAL_SD_ReadBlocks(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK) {
		return MSD_ERROR;
	}
	
	return MSD_OK;
}

/**
  * @brief  Writes block(s) to a specified address in an SD card, in polling mode. 
  * @param  pData: Pointer to the buffer that will contain the data to transmit
  * @param  WriteAddr: Address from where data is to be written  
  * @param  BlockSize: SD card data block size, that should be 512
  * @param  NumOfBlocks: Number of SD blocks to write
  * @retval SD status
  */
uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks) {
	if (HAL_SD_WriteBlocks(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK) {
		return MSD_ERROR;
	}
	
	return MSD_OK;
}

/**
  * @brief  Reads block(s) from a specified address in an SD card, in DMA mode.
  * @param  pData: Pointer to the buffer that will contain the data to transmit
  * @param  ReadAddr: Address from where data is to be read  
  * @param  BlockSize: SD card data block size, that should be 512
  * @param  NumOfBlocks: Number of SD blocks to read 
  * @retval SD status
  */
uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks) {
	uint8_t SD_state = MSD_OK;

	/* Read block(s) in DMA transfer mode */
	if (HAL_SD_ReadBlocks_DMA(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK) {
		SD_state = MSD_ERROR;
	}

	/* Wait until transfer is complete */
	if (SD_state == MSD_OK) {
		if (HAL_SD_CheckReadOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK) {
			SD_state = MSD_ERROR;
		} else {
			SD_state = MSD_OK;
		}
	}

	return SD_state; 
}

/**
  * @brief  Writes block(s) to a specified address in an SD card, in DMA mode.
  * @param  pData: Pointer to the buffer that will contain the data to transmit
  * @param  WriteAddr: Address from where data is to be written  
  * @param  BlockSize: SD card data block size, that should be 512
  * @param  NumOfBlocks: Number of SD blocks to write 
  * @retval SD status
  */
uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks) {
	uint8_t SD_state = MSD_OK;

	/* Write block(s) in DMA transfer mode */
	if (HAL_SD_WriteBlocks_DMA(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK) {
		SD_state = MSD_ERROR;
	}

	/* Wait until transfer is complete */
	if (SD_state == MSD_OK) {
		if(HAL_SD_CheckWriteOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK) {
			SD_state = MSD_ERROR;
		} else {
			SD_state = MSD_OK;
		}
	}

	return SD_state;  
}

/**
  * @brief  Erases the specified memory area of the given SD card. 
  * @param  StartAddr: Start byte address
  * @param  EndAddr: End byte address
  * @retval SD status
  */
uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr) {
	if (HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr) != SD_OK) {
		return MSD_ERROR;
	}
	
	return MSD_OK;
}

/**
  * @brief  Initializes the SD MSP.
  * @param  None
  * @retval None
  */
static void SD_MspInit(void) {
	static DMA_HandleTypeDef dmaRxHandle;
	static DMA_HandleTypeDef dmaTxHandle;
	SD_HandleTypeDef *hsd = &uSdHandle;
	uint16_t gpio_af;
	
	/* Get GPIO alternate function */
#if defined(GPIO_AF12_SDIO)
	gpio_af = GPIO_AF12_SDIO;
#endif
#if defined(GPIO_AF12_SDMMC1)
	gpio_af = GPIO_AF12_SDMMC1;
#endif
	
	/* Enable SDIO clock */
	__HAL_RCC_SDIO_CLK_ENABLE();

	/* Enable DMA2 clocks */
	__DMAx_TxRx_CLK_ENABLE();

	/* Detect pin, write protect pin */
#if FATFS_USE_DETECT_PIN > 0
	TM_GPIO_Init(FATFS_DETECT_PORT, FATFS_DETECT_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
#endif
#if FATFS_USE_WRITEPROTECT_PIN > 0
	TM_GPIO_Init(FATFS_WRITEPROTECT_PORT, FATFS_WRITEPROTECT_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
#endif
	
	/* SDIO/SDMMC pins */
#if FATFS_SDIO_4BIT == 1
	TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, gpio_af);
#else
	TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_8 | GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, gpio_af);
#endif
	TM_GPIO_InitAlternate(GPIOD, GPIO_PIN_2, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, gpio_af);

	/* NVIC configuration for SDIO interrupts */
	HAL_NVIC_SetPriority(SDIO_IRQn, 5, 0);
	HAL_NVIC_EnableIRQ(SDIO_IRQn);

	/* Configure DMA Rx parameters */
	dmaRxHandle.Init.Channel             = SD_DMAx_Rx_CHANNEL;
	dmaRxHandle.Init.Direction           = DMA_PERIPH_TO_MEMORY;
	dmaRxHandle.Init.PeriphInc           = DMA_PINC_DISABLE;
	dmaRxHandle.Init.MemInc              = DMA_MINC_ENABLE;
	dmaRxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
	dmaRxHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
	dmaRxHandle.Init.Mode                = DMA_PFCTRL;
	dmaRxHandle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
	dmaRxHandle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
	dmaRxHandle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
	dmaRxHandle.Init.MemBurst            = DMA_MBURST_INC4;
	dmaRxHandle.Init.PeriphBurst         = DMA_PBURST_INC4;

	dmaRxHandle.Instance = SD_DMAx_Rx_STREAM;

	/* Associate the DMA handle */
	__HAL_LINKDMA(hsd, hdmarx, dmaRxHandle);

	/* Deinitialize the stream for new transfer */
	HAL_DMA_DeInit(&dmaRxHandle);

	/* Configure the DMA stream */
	HAL_DMA_Init(&dmaRxHandle);

	/* Configure DMA Tx parameters */
	dmaTxHandle.Init.Channel             = SD_DMAx_Tx_CHANNEL;
	dmaTxHandle.Init.Direction           = DMA_MEMORY_TO_PERIPH;
	dmaTxHandle.Init.PeriphInc           = DMA_PINC_DISABLE;
	dmaTxHandle.Init.MemInc              = DMA_MINC_ENABLE;
	dmaTxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
	dmaTxHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
	dmaTxHandle.Init.Mode                = DMA_PFCTRL;
	dmaTxHandle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
	dmaTxHandle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
	dmaTxHandle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
	dmaTxHandle.Init.MemBurst            = DMA_MBURST_INC4;
	dmaTxHandle.Init.PeriphBurst         = DMA_PBURST_INC4;

	dmaTxHandle.Instance = SD_DMAx_Tx_STREAM;

	/* Associate the DMA handle */
	__HAL_LINKDMA(hsd, hdmatx, dmaTxHandle);

	/* Deinitialize the stream for new transfer */
	HAL_DMA_DeInit(&dmaTxHandle);

	/* Configure the DMA stream */
	HAL_DMA_Init(&dmaTxHandle); 

	/* NVIC configuration for DMA transfer complete interrupt */
	HAL_NVIC_SetPriority(SD_DMAx_Rx_IRQn, 6, 0);
	HAL_NVIC_EnableIRQ(SD_DMAx_Rx_IRQn);

	/* NVIC configuration for DMA transfer complete interrupt */
	HAL_NVIC_SetPriority(SD_DMAx_Tx_IRQn, 6, 0);
	HAL_NVIC_EnableIRQ(SD_DMAx_Tx_IRQn);
}


/**
  * @brief  Get SD information about specific SD card.
  * @param  CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
  * @retval None 
  */
void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypedef *CardInfo) {
	/* Get SD card Information */
	HAL_SD_Get_CardInfo(&uSdHandle, CardInfo);
}