#include <stdio.
h>
#include "platform.h"
#include "xscugic.h"
#include"xtmrctr.h"
#include "xil_printf.h"
#include "sleep.h"
#include "xtime_l.h"
#include "xgpio.h"
#include "xparameters.h"
#include "xscutimer.h"
#include "xiicps.h"
#include "timer_f.h"
#include "xadcps.h"
#include "sleep.h"
#include "xtime_l.h" // Needed to use the global timer
#include "Defines.h"//OLED Library
#include "SH1106_Screen.h"//OLED Library
#define XADC_DEVICE_ID XPAR_XADCPS_0_DEVICE_ID//ADC Device ID
static XAdcPs XAdcInst; /* XADC driver instance */
int count = 0; //Variable to see the time that it takes to complete the flag (the
response time to a change in input)
int Left_Data_Val = 0; //Left Sensor Input may need to change type to u16
int Right_Data_Val = 0; //Right Sensor Input
int Upper_Data_Val = 0; //Left Sensor Input may need to change type to u16
int Lower_Data_Val = 0; //Right Sensor Input
int Data_Diff = 0; //Data difference between 2 inputs
int Data_Diff_H = 0; //Data difference between 2 inputs (horizontal)
int go_left = 0; //Data difference between 2 inputs
int flag = 0; //interrupt flag
int pwm_top = 0;//Pwm signal to top MOSFET
int pwm_bottom = 0;//PWM signal to bottom MOSFET
int pwm_LR = 0;//PWM signal to Left/Right MOSFET
/***************************************************************/
int XAdcConfig(u16 XAdcDeviceId, u32 Mode) { //ADC configuration
int Status;
XAdcPs_Config *ConfigPtr;
XAdcPs *XAdcInstPtr = &XAdcInst;
ConfigPtr = XAdcPs_LookupConfig(XAdcDeviceId);
if (ConfigPtr == NULL) {return XST_FAILURE;}
XAdcPs_CfgInitialize(XAdcInstPtr, ConfigPtr, ConfigPtr->BaseAddress);
Status = XAdcPs_SelfTest(XAdcInstPtr);
if (Status != XST_SUCCESS) {return XST_FAILURE;}
XAdcPs_SetSequencerMode(XAdcInstPtr,Mode);
return XST_SUCCESS;
};
/*****************************************************************************/
/************************** Constant Definitions *****************************/
/*****************************************************************************/
// SCU timer settings
#define SCU_TIMER_VALUE (0x319750) // 1ms @ 650MHz/2 (3ns)
// Interrupt settings
// in steps of 8, lower number high priority
#define SCU_TIMER_INTR_PRI (0xA0)
#define SCU_TIMER_INTR_TRIG (0x03)
/*****************************************************************************/
/************************** Driver instances and pointers ********************/
/*****************************************************************************/
static XScuTimer my_Timer; // SCU Timer instance
static XScuGic my_Gic ; // GIC instance
/*****************************************************************************/
/************************** Prototype of Interrupt Handler (aka ISR) *********/
/*****************************************************************************/
void my_timer_interrupt_handler(void * CallBackRef);
/*****************************************************************************/
/************************** Prototype of API Functions **********************/
/*****************************************************************************/
int Init_GIC(void);
int Init_SCUTimer(void);
int addScuTimerToInterruptSystem(void);
/*****************************************************************************/
/************************** Main program *************************************/
/*****************************************************************************/
#define PWM_PERIOD 100000// PWM period in nano-seconds (5ms)
XTmrCtr TimerCounterInst; /* The instance of the Timer Counter */
XTmrCtr TimerCounterInst1; /* The instance of the Timer Counter */
XTmrCtr TimerCounterInst2; /* The instance of the Timer Counter */
void rgbled_init (unsigned int period, unsigned char width){
u32 pwm_period;
u32 duty_cycle;
pwm_period = period; // pwm_period in nano seconds
duty_cycle = width;
PwmInit(&TimerCounterInst,TMR0_DEVICE_ID);
PwmInit(&TimerCounterInst1,TMR1_DEVICE_ID);
PwmInit(&TimerCounterInst2,TMR2_DEVICE_ID);
PwmConfig(&TimerCounterInst, pwm_period, duty_cycle);
PwmConfig(&TimerCounterInst1, pwm_period, duty_cycle);
PwmConfig(&TimerCounterInst2, pwm_period, duty_cycle);
}
/*****************************************************************************/
void switch_table (u16 VccPintRawData, u16 VccPintRawData2) { //Lookup Table to
decide to activate motor or not and display current status
printNew(1, 1, " ");
if (VccPintRawData > 6700 && go_left == 1) {
pwm_top = 1;
pwm_bottom = 70;
printDisplay(1, 1, "Motor Turning Left");
}
else if (VccPintRawData > 6700 && go_left == 0) {
pwm_top = 70;
pwm_bottom = 1;
printDisplay(1, 1, "Motor Turning Right");
}
else {
pwm_top = 1;
pwm_bottom = 1;
printDisplay(1, 1, "Motor Not Turning");
}
if (VccPintRawData2 > 6700) {
pwm_LR = 70;
printDisplay(2, 20, "Motor Turning Up");
}
else {
pwm_LR = 1;
printDisplay(2, 20, "Motor Not Turning Up");
}
u32 duty_cycle_t;
u32 duty_cycle_b;
u32 duty_cycle_lr;
duty_cycle_t = pwm_top * PWM_PERIOD / 100;
duty_cycle_b = pwm_bottom * PWM_PERIOD / 100;
duty_cycle_lr = pwm_LR * PWM_PERIOD / 100;
PwmConfig(&TimerCounterInst, PWM_PERIOD, duty_cycle_t);//PIN AR 9 for Left
PwmConfig(&TimerCounterInst1, PWM_PERIOD, duty_cycle_b);//PIN AR 5 for right
INPUT A5 A4
PwmConfig(&TimerCounterInst2, PWM_PERIOD, duty_cycle_lr); //PIN AR 11 INPUT
A0 A2
}
/*****************************************************************************/
int adc_channels[4] = {15,13,5,6};
/*****************************************************************************/
int main(){
init_platform();//OLED Platform Initialisation
initDisplay();//OLED Platform Initialisation
int Status;
double duty_cycle = 0.2; // duty cycle (e.g. 0.6 means 60%)
u32 high_time = duty_cycle*PWM_PERIOD;
Status = XAdcConfig(XADC_DEVICE_ID, XADCPS_SEQ_MODE_CONTINPASS);
if (Status != XST_SUCCESS) {return XST_FAILURE;}
PwmInit(&TimerCounterInst,TMR0_DEVICE_ID);
PwmInit(&TimerCounterInst1,TMR1_DEVICE_ID);
PwmInit(&TimerCounterInst2,TMR2_DEVICE_ID);
PwmConfig(&TimerCounterInst, PWM_PERIOD, high_time);
PwmConfig(&TimerCounterInst1, PWM_PERIOD, high_time);
PwmConfig(&TimerCounterInst2, PWM_PERIOD, high_time);
/* Initialize PS platform */
init_platform();
/* Initialize SCUGIC */
if( Init_GIC() == XST_SUCCESS){
xil_printf("\nSCUGIC initialized \r\n");
}
/* Initialize SCU Timer */
if (Init_SCUTimer() == XST_SUCCESS){
xil_printf("SCU Timer initialized \r\n");
}
/* Add SCU Timer to interrupt system */
if (addScuTimerToInterruptSystem() == XST_SUCCESS){
xil_printf("SCU Timer added to interrupt system \r\n");
}
/* Enable interrupts */
xil_printf("Enabling interrupts \r\n");
Xil_ExceptionEnable(); // Initialize exception handeling in the ARM processor
/* Start SCU timer */
xil_printf("Starting the SCU Timer \r\n");
XScuTimer_Start(&my_Timer);
xil_printf("Entering main loop \r\n");
while (1)
{
// Do nothing
if (flag == 1)
{
xil_printf("You executed the program since %d milliseconds\r\n", count+
+);
Left_Data_Val = XAdcPs_GetAdcData(&XAdcInst,XADCPS_CH_AUX_MIN +
adc_channels[1]);
Right_Data_Val = XAdcPs_GetAdcData(&XAdcInst,XADCPS_CH_AUX_MIN +
adc_channels[2]);
Upper_Data_Val = XAdcPs_GetAdcData(&XAdcInst,XADCPS_CH_AUX_MIN +
adc_channels[3]);
Lower_Data_Val = XAdcPs_GetAdcData(&XAdcInst,XADCPS_CH_AUX_MIN +
adc_channels[4]);
Data_Diff = Left_Data_Val - Right_Data_Val;
Data_Diff_H = Upper_Data_Val - Lower_Data_Val;
go_left = 0;
if (Data_Diff < 0) {
Data_Diff = -1 * Data_Diff;
go_left = 1;
}
if (Data_Diff_H < 0) {
Data_Diff_H = -1 * Data_Diff_H;
}
printf("%d\n", Data_Diff);
printf("%d\n", Data_Diff_H);
switch_table(Data_Diff, Data_Diff_H);
flag = 0;
}
}
return 0;
}
/*****************************************************************************/
/************************** SCU Timer Interrupt Handler (aka ISR) ************/
/*****************************************************************************/
void my_timer_interrupt_handler(void * CallBackRef){
/* Clear interrupt status */
XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;
if( XScuTimer_IsExpired(TimerInstancePtr))
{
XScuTimer_ClearInterruptStatus(TimerInstancePtr);
}
/* Add below your specific interrupt code */
flag = 1;
}
/*****************************************************************************/
/************************** Definitions of (API) Functions **********************/
/*****************************************************************************/
int Init_GIC(void){
XScuGic_Config *Gic_Config= NULL;
int status;
/* ---------------------------------------------------------------------
* ------------ STEP 1: DEVICE LOOK-UP ------------
* -------------------------------------------------------------------- */
// Look up the configuration information for the GIC
Gic_Config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
if (Gic_Config== NULL)
{
status = XST_FAILURE;
return status;
}
/* ---------------------------------------------------------------------
* ------------ STEP 2: DRIVER INITIALISATION ------------
* -------------------------------------------------------------------- */
// Configure the GIC with the configuration information
status = XScuGic_CfgInitialize(&my_Gic, Gic_Config, Gic_Config->CpuBaseAddress);
/* ---------------------------------------------------------------------
* ------------ STEP 3: SELF TEST ------------
* -------------------------------------------------------------------- */
status = XScuGic_SelfTest(&my_Gic);
if (status != XST_SUCCESS){
xil_printf("GIC config init failed \r\n");
return XST_FAILURE;
}
/* ---------------------------------------------------------------------
* ----------------------- STEP 4: CONNECT GIC ----
* -------------------------------------------------------------------- */
// Initialise exception logic on the ARM Cortex A9
Xil_ExceptionInit();
/* Connect the interrupt controller interrupt handler to the
* hardware interrupt handling logic in the processor. */
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
&my_Gic);
/* === END CONFIGURATION SEQUENCE === */
return XST_SUCCESS;
}
int Init_SCUTimer(void){
// XScuTimer SCUTimer;
XScuTimer_Config *Timer_Config= NULL;
int status;
/* === START CONFIGURATION SEQUENCE === */
/* ---------------------------------------------------------------------
* ------------ STEP 1: DEVICE LOOK-UP ------------
* -------------------------------------------------------------------- */
// Look up the configuration information for the SCU Timer
Timer_Config= XScuTimer_LookupConfig(XPAR_PS7_SCUTIMER_0_DEVICE_ID);
if (Timer_Config == NULL)
{
status = XST_FAILURE;
return status;
}
/* ---------------------------------------------------------------------
* ------------ STEP 2: DRIVER INITIALISATION ------------
* -------------------------------------------------------------------- */
// Configure the SCU timer with the configuration information
status = XScuTimer_CfgInitialize(&my_Timer, Timer_Config, Timer_Config->BaseAddr);
if (status != XST_SUCCESS){
xil_printf("SCU Timer cfg init failed \r\n");
return status;
}
/* ---------------------------------------------------------------------
* ------------ STEP 3: SELF TEST ------------
* -------------------------------------------------------------------- */
status = XScuTimer_SelfTest(&my_Timer);
if (status != XST_SUCCESS){
xil_printf("SCU Timer cfg init failed \r\n");
return status;
}
/* ---------------------------------------------------------------------
* ------------ STEP 4: ENABLE INTERRUPTS ------------------------------
* -------------------------------------------------------------------- */
XScuTimer_EnableInterrupt(&my_Timer);
/* ---------------------------------------------------------------------
* ------------ STEP 4: INIT COUNTER OF SCU TIMER ---------------------
* -------------------------------------------------------------------- */
XScuTimer_EnableAutoReload(&my_Timer);
XScuTimer_LoadTimer(&my_Timer, SCU_TIMER_VALUE);
/* === END CONFIGURATION SEQUENCE === */
return XST_SUCCESS;
}
int addScuTimerToInterruptSystem(void)
{
int status;
/* Connect a device driver handler for the XScuTimer */
// Assign (connect) the interrupt handler that you wrote for our timer
status = XScuGic_Connect(&my_Gic,
XPAR_PS7_SCUTIMER_0_INTR,
(Xil_ExceptionHandler)
my_timer_interrupt_handler,
(void *) &my_Timer);
if (status != XST_SUCCESS)
{
return XST_FAILURE;
}
/* Set priority and trigger type */
XScuGic_SetPriorityTriggerType(&my_Gic,
XPAR_PS7_SCUTIMER_0_INTR,
SCU_TIMER_INTR_PRI,
SCU_TIMER_INTR_TRIG);
/* Enable the interrupt on the GIC for SCU Timer */
XScuGic_Enable(&my_Gic, XPAR_PS7_SCUTIMER_0_INTR);
/* Return initialisation result to calling code */
return status;
}