/** * \brief Perform complete pin(s) configuration; general attributes and PIO init * if necessary. * * \param p_pio Pointer to a PIO instance. * \param ul_type PIO type. * \param ul_mask Bitmask of one or more pin(s) to configure. * \param ul_attribute Pins attributes. * * \return Whether the pin(s) have been configured properly. */ uint32_t pio_configure(Pio *p_pio, const pio_type_t ul_type, const uint32_t ul_mask, const uint32_t ul_attribute) { /* Configure pins */ switch (ul_type) { case PIO_PERIPH_A: case PIO_PERIPH_B: # if (SAM3S || SAM3N || SAM4S) case PIO_PERIPH_C: case PIO_PERIPH_D: # endif pio_set_peripheral(p_pio, ul_type, ul_mask); pio_pull_up(p_pio, ul_mask, (ul_attribute & PIO_PULLUP)); break; case PIO_INPUT: pio_set_input(p_pio, ul_mask, ul_attribute); break; case PIO_OUTPUT_0: case PIO_OUTPUT_1: pio_set_output(p_pio, ul_mask, (ul_type == PIO_OUTPUT_1), (ul_attribute & PIO_OPENDRAIN) ? 1 : 0, (ul_attribute & PIO_PULLUP) ? 1 : 0); break; default: return 0; } return 1; }
/** * \brief Perform a HW initialization to the PHY and set up clocks. * * This should be called only once to initialize the PHY pre-settings. * The PHY address is the reset status of CRS, RXD[3:0] (the emacPins' pullups). * The COL pin is used to select MII mode on reset (pulled up for Reduced MII). * The RXDV pin is used to select test mode on reset (pulled up for test mode). * The above pins should be predefined for corresponding settings in resetPins. * The GMAC peripheral pins are configured after the reset is done. * * \param p_gmac Pointer to the GMAC instance. * \param uc_phy_addr PHY address. * \param ul_mck GMAC MCK. * * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout. */ uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t mck) { uint8_t uc_rc; uint8_t uc_phy; #if 0 // chrishamm pio_set_output(PIN_GMAC_RESET_PIO, PIN_GMAC_RESET_MASK, 1, false, true); pio_set_input(PIN_GMAC_INT_PIO, PIN_GMAC_INT_MASK, PIO_PULLUP); pio_set_peripheral(PIN_GMAC_PIO, PIN_GMAC_PERIPH, PIN_GMAC_MASK); #endif ethernet_phy_reset(GMAC,uc_phy_addr); /* Configure GMAC runtime clock */ uc_rc = gmac_set_mdc_clock(p_gmac, mck); if (uc_rc != GMAC_OK) { return 0; } /* Check PHY Address */ uc_phy = ethernet_phy_find_valid(p_gmac, uc_phy_addr, 0); if (uc_phy == 0xFF) { return 0; } if (uc_phy != uc_phy_addr) { ethernet_phy_reset(p_gmac, uc_phy_addr); } return uc_rc; }
/************************************************************************ Configuration of the Pulse Width Modulation (PWM). ************************************************************************/ void PWMInit(void){ pmc_enable_periph_clk(ID_PWM); pwm_channel_disable(PWM, PWM_CHANNEL_3); pwm_channel_disable(PWM, PWM_CHANNEL_2); pwm_clock_t clock_setting = { .ul_clka = 50 * 19999, .ul_clkb = 0, .ul_mck = sysclk_get_cpu_hz() }; pwm_init(PWM, &clock_setting); InitPIN40(); InitPIN38(); } /************************************************************************ Initiation of digital pin 40 on the Arduino Due board for PWM. ************************************************************************/ void InitPIN40(void) { PWMPin40.channel = PWM_CHANNEL_3; PWMPin40.ul_prescaler = PWM_CMR_CPRE_CLKA; PWMPin40.ul_duty = 0; PWMPin40.ul_period = 19999; pwm_channel_init(PWM, &PWMPin40); pio_set_peripheral(PIOC, PIO_PERIPH_B, PIO_PC8B_PWML3); pwm_channel_enable(PWM, PWM_CHANNEL_3); }
/************************************************************************ Initiation of digital pin 40 on the Arduino Due board for PWM. ************************************************************************/ void InitPIN38(void){ PWMPin38.channel = PWM_CHANNEL_2; PWMPin38.ul_prescaler = PWM_CMR_CPRE_CLKA; PWMPin38.ul_duty = 0; PWMPin38.ul_period = 19999; pwm_channel_init(PWM, &PWMPin38); pio_set_peripheral(PIOC, PIO_PERIPH_B, PIO_PC6B_PWML2); pwm_channel_enable(PWM, PWM_CHANNEL_2); }
void sam_debug_early_init(void) { pmc_enable_periph_clk(ID_UART); pmc_enable_periph_clk(ID_PIOA); pio_set_peripheral(PIOA, PIO_PERIPH_A, PIO_PA8); pio_set_peripheral(PIOA, PIO_PERIPH_A, PIO_PA9); sam_uart_opt_t opt; opt.ul_mck = 84000000; opt.ul_baudrate = 115200; opt.ul_mode = UART_MR_PAR_NO | UART_MR_CHMODE_NORMAL; NVIC_DisableIRQ(UART_IRQn); uart_init(UART, &opt); uart_enable(UART); }
/* Funktionen initierar PWM-signalen */ void pwm_setup(void) { pmc_enable_periph_clk(ID_PWM); pwm_channel_disable(PWM, PWM_CHANNEL); pwm_clock_t clock_setting = { .ul_clka = PWM_FREQUENCY * PWM_PERIOD, .ul_clkb = 0, .ul_mck = SYS_CLOCK }; pwm_init(PWM, &clock_setting); pwm_channel_instance.alignment = PWM_ALIGN_LEFT; pwm_channel_instance.polarity = PWM_LOW; pwm_channel_instance.ul_prescaler = PWM_CMR_CPRE_CLKA; pwm_channel_instance.ul_period = PWM_PERIOD; pwm_channel_instance.ul_duty = PWM_INIT_DUTY_CYCLE; pwm_channel_instance.channel = PWM_CHANNEL; pwm_channel_init(PWM, &pwm_channel_instance); pio_set_peripheral(PWM_PIO, PWM_PERIPHERAL, PWM_PIN); pwm_channel_enable(PWM, PWM_CHANNEL); } /* Funktionen uppdaterar PWM-signalens duty-cycle */ void update_pwm(int ul_duty) { // Kontrollerar så att angiven duty-cycle befinner sig inom rätt område (0-1000). if(ul_duty < PWM_MIN_DUTY_CYCLE) { pwm_channel_update_duty(PWM, &pwm_channel_instance, PWM_MIN_DUTY_CYCLE); } else if(ul_duty > PWM_MAX_DUTY_CYCLE) { pwm_channel_update_duty(PWM, &pwm_channel_instance, PWM_MAX_DUTY_CYCLE); } else { pwm_channel_update_duty(PWM, &pwm_channel_instance, ul_duty); } } /* Funktionen initierar motor-shielden */ void motor_shield_setup(void) { ioport_set_pin_dir(PIO_PD8_IDX, IOPORT_DIR_OUTPUT); ioport_set_pin_level(PIO_PD8_IDX, IOPORT_PIN_LEVEL_HIGH); ioport_set_pin_dir(PIO_PC21_IDX, IOPORT_DIR_OUTPUT); ioport_set_pin_level(PIO_PC21_IDX, IOPORT_PIN_LEVEL_LOW); }
void twi_init () { //Enable peripheral clock AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_TWI); //PIO PINS SETUP FOR SPI BUS //setup PIO pins as peripheral pio_set_peripheral(AT91C_PA3_TWD|AT91C_PA4_TWCK,0,FALSE); //set opendrain AT91C_BASE_PIOA->PIO_MDER=AT91C_PA3_TWD|AT91C_PA4_TWCK; //* Disable interrupts AT91C_BASE_TWI->TWI_IDR = (unsigned int) -1; //* Reset peripheral AT91C_BASE_TWI->TWI_CR = AT91C_TWI_SWRST; twi_setclk(USPI_TWI_CLK_HZ); }
void pwm_init() { // Enable PWMC peripheral clock AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PWMC; pPwm->PWMC_CH[0].PWMC_CMR= #ifdef LOWFREQ AT91C_PWMC_CPRE&0x4 | //MCK/16 #else AT91C_PWMC_CPRE&0x3 | //MCK/8 #endif AT91C_PWMC_CALG&0 | //left aligned AT91C_PWMC_CPOL ; //starts from high pPwm->PWMC_CH[0].PWMC_CPRDR=192;//clock multiplier pPwm->PWMC_CH[0].PWMC_CDTYR=2;//duty cycle //setup PIO pins as peripheral pio_set_peripheral(AT91C_PA0_PWM0,0,TRUE); //set outputs AT91C_BASE_PIOA->PIO_OER=AT91C_PA0_PWM0; }
/** * \brief Application entry point for PWM PDC example. * * \return Unused (ANSI-C compatibility). */ int main(void) { /* Initialize the SAM system */ sysclk_init(); board_init(); /* Configure the console uart for debug infomation */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Enable PWM peripheral clock */ pmc_enable_periph_clk(ID_PWM); /*A Disable PWM channels - Register: PWM_DIS (PWM Disable) - Kanal 0: Motor1_X - Kanal 1: Motor1_Y - Kanal 2: Motor1_Z - Kanal 3: Referenzsignals */ pwm_channel_disable(PWM, PWM_CHANNEL_0); pwm_channel_disable(PWM, PWM_CHANNEL_1); pwm_channel_disable(PWM, PWM_CHANNEL_2); pwm_channel_disable(PWM, PWM_CHANNEL_3); /*A PWM-Leitungen (C.2 - C.9) im Prozessor vom PIO-Controller trennen und auf peripheral Funktion B setzen */ for (int pinId = 2; pinId <= 9; pinId++) { pio_set_peripheral(PIOC, PIO_TYPE_PIO_PERIPH_B, (1u << pinId)); } /*A Clock einstellen - Set PWM clock A for all channels, clock B not used */ pwm_clock_t clock_setting = { .ul_clka = PWM_FREQUENCY * PERIOD_VALUE, .ul_clkb = 0, .ul_mck = sysclk_get_cpu_hz() // diese Funktion gibt 84 Mhz zurück! }; pwm_init(PWM, &clock_setting); /*A Kanäle 0,1,2 als synchron festlegen */ // zunächst die generellen Eigenschaften der synchronen Channels initialisieren pwm_channel_t sync_channel = { /* die Motor Kanäle sollen alle Center aligned sein */ .alignment = PWM_ALIGN_CENTER, /* die Motor Kanäle sollen mit Low Polarität starten */ .polarity = PWM_LOW, /* Alle Motor Kanäle sollen Clock A verwenden, da sie mit doppelter Basisfrequenz getaktet werden müssen wegen Center aligned */ .ul_prescaler = PWM_CMR_CPRE_CLKA, /* Periode einstellen */ .ul_period = PERIOD_VALUE, /* Duty cycle initial setzen */ .ul_duty = INIT_DUTY_VALUE, /* der channel soll synchron sein */ .b_sync_ch = true, .b_deadtime_generator = true, .us_deadtime_pwmh = 1, .us_deadtime_pwml = 1 }; /* als erstes dann den Channel 0 initialisieren, indem nur das Channel Attribut in der Struktur von oben neu gesetzt wird, der REst bleibt gleich... */ sync_channel.channel = PWM_CHANNEL_0; pwm_channel_init(PWM, &sync_channel); // das gleiche dann mit den beiden anderen zu synchronisierenden Channels sync_channel.channel = PWM_CHANNEL_1; pwm_channel_init(PWM, &sync_channel); sync_channel.channel = PWM_CHANNEL_2; pwm_channel_init(PWM, &sync_channel); /* * Initialize PWM synchronous channels * Synchronous Update Mode: Automatic update duty cycle value by the PDC * and automatic update of synchronous channels. The update occurs when * the Update Period elapses (MODE 2 --> Vorsicht vor Verwirrung: dies entspricht der "Methode 3" aus dem Datasheet!). * Synchronous Update Period = MAX_SYNC_UPDATE_PERIOD. */ pwm_sync_init(PWM, PWM_SYNC_UPDATE_MODE_2, MAX_SYNC_UPDATE_PERIOD); /* * Request PDC transfer as soon as the synchronous update period elapses */ pwm_pdc_set_request_mode(PWM, PWM_PDC_UPDATE_PERIOD_ELAPSED, (1 << 0)); /* Aktiviere alle synchronen channel durch aktivieren von channel 0, channel 1 und 2 werden automatisch synchron mit gestartet zusätzlich noch den Refernzchannel "synchron" mitstarten die ASF funktion channel_enable erlaubt leider nur die Übergabe eines Kanals, also müssen wir hier wohl mit direktem Zugriff auf das Register arbeiten */ pwm_channel_enable(PWM, PWM_CHANNEL_0); // ref channel funktioniert noch nicht, muss noch debugged werden pwm_channel_enable(PWM, PWM_CHANNEL_3); pmc_enable_periph_clk(ID_PIOA); pio_set_output(PIOA, PIO_PA23, LOW, DISABLE, ENABLE); int angle = 0; int up = 1; float sinus = 0; float a; while (1) { pio_set(PIOA, PIO_PA23); for (int i = 0; i < 1000; i++) { sinus = sin(0.343543); a = sinus; } pio_clear(PIOA, PIO_PA23); delay_us(4); /*display_menu(); uint32_t angle = get_num_value(); struct SV pwm = get_vector_for_angle(angle); SVPWM(pwm.u, pwm.v, pwm.w); printf("The angle is %i degrees.", angle); for (int i = 0; i <= 360; i++) { struct SV pwm = get_vector_for_angle(i); SVPWM(pwm.u, pwm.v, pwm.w); printf("%i Grad\r\n", i); delay_ms(40); } for (int i = 360; i >= 0; i--) { struct SV pwm = get_vector_for_angle(i); SVPWM(pwm.u, pwm.v, pwm.w); printf("%i Grad\r\n", i); delay_ms(40); }*/ } }