int main(void) { unsigned int i, j; Board_init(); PWM_init(PWM_PORTX11 | PWM_PORTY04 | PWM_PORTY10 | PWM_PORTY12 | PWM_PORTZ06, FIRST_PERIOD); printf("Uno PWM Test Harness\r\n"); printf("Ramping PWM from %d-%d%% in 10%% steps at %d with a delay between\r\n", MIN_RAMP, MAX_RAMP, FIRST_PERIOD); unsigned char ch = 0; for (j = MIN_RAMP; j <= MAX_RAMP; j += 100) { PWM_setDutyCycle(PWM_PORTX11, j); PWM_setDutyCycle(PWM_PORTY04, j + 20); PWM_setDutyCycle(PWM_PORTY10, j + 40); PWM_setDutyCycle(PWM_PORTY12, j + 60); PWM_setDutyCycle(PWM_PORTZ06, j + 80); printf("Outputting %d%% Duty Cycle\r\n", j / 10); DELAY(10000); } printf("Setting Period to %d and repeating ramp\r\n", SECOND_PERIOD); PWM_end(); PWM_init(PWM_PORTX11 | PWM_PORTY04 | PWM_PORTY10 | PWM_PORTY12 | PWM_PORTZ06, SECOND_PERIOD); for (j = MIN_RAMP; j <= MAX_RAMP; j += 100) { PWM_setDutyCycle(PWM_PORTX11, j); PWM_setDutyCycle(PWM_PORTY04, j + 20); PWM_setDutyCycle(PWM_PORTY10, j + 40); PWM_setDutyCycle(PWM_PORTY12, j + 60); PWM_setDutyCycle(PWM_PORTZ06, j + 80); printf("Outputting %d%% Duty Cycle\r\n", j / 10); DELAY(10000); } PWM_end(); return 0; }
int main(void) { uint8_t current_state = 0; // Used to store the current state of TX state machine uint16_t pulse_count = 0; // Used to store the current number of pulses GPIO_init(); init_timer_0A(); init_timer_0B(); nvic_init(); PWM_init(); // IR Rx GPIO port (PB4) for asynch receive init_IR_rx(); // Delay for microcontroller clock to stabilize delay_timer_0A(500); current_state = 1; // Activate the tx_state_machine while(1) { // If the 562us timer expired then it is time to update state machine /* if (mod_period_flag) { mod_period_flag = 0; tx_state_machine(¤t_state, &pulse_count, IR_address, IR_data_GREEN); //<--- TX CHANGE HERE!! } */ // If RX port senses an edge, store the timer count if (rx_interrupt_flag) { rx_interrupt_flag = 0; rx_handler(); } } }
int main(void) { LEDS_init(); /* init the LEDs for this board */ IO_init(FAST_IO); PWM_init(PWM_1|PWM_4); /* P0.0, P0.8 */ PWM_frequency(50); /* 50 Hz PWM output, 20ms */ LEDS_on(LED3); while(1) { if (flashen_button()) { PWM_pulsewidth_us (PWM_1, 1500); // Center PWM_pulsewidth_us (PWM_4, 1500); // Center LEDS_on(LED2); } else { PWM_pulsewidth_us (PWM_1, 1000); // 45º left PWM_pulsewidth_us (PWM_4, 2000); // 45º right LEDS_off(LED2); } } }
int Main() { U32 freq=2500; led_key_init(); //初始化LED和KEY PWM_init(); //初始化PWM定时器 while(1) { if( !(GPGDAT &( 1<<0 )) ){ // K1 PWM值降低 freq =freq+300; if(freq>5000) freq=2500; TCMPB0 = freq; //数据手册里说:PWM功能可以通过使用TCMPBn实现。PWM频率由TCNTBn决定。 //这里通过改变TCMPB0来改变PWM的值。 //减小TCMPBn可以提高PWM值。增大TCMPBn可以降低PWM值。 led2_1_on(); } else if(!(GPGDAT &( 1<<3 )) ){ // K2 PWM值增加 freq =freq-300; if(freq<1000) freq=2500; TCMPB0 = freq; led3_4_on(); } else if(!(GPGDAT &( 1<<5 )) ){ // K3 关闭蜂鸣器输出 ESC_PWM(); } else if(!(GPGDAT &( 1<<6 )) ){ // K4 打开蜂鸣器输出 OPEN_PWM(); } } return 0; }
int main(void) { CLK_init(); SYS_init(); UART_init(); ADC_init(); PWM_init(); //Initialize PWM (servos not running) PWM_dutySet(500, 200); _bis_SR_register(LPM0_bits + GIE); // interrupts enabled while(1) { //_ldrL_ADCVal = _readADC(INCH_4); //Read ADC input on P2.1 //_ldrR_ADCVal = _readADC(INCH_5); //Read ADC input on P2.2 UART_puts((char *)"\n\r"); UART_puts((char *)"_ldrL_ADCVal: "); UART_outdec(_ldrL_ADCVal, 0); UART_puts((char *)"\n\r"); UART_puts((char *)"_ldrR_ADCVal: "); UART_outdec(_ldrR_ADCVal, 0); _delay_cycles(125000); P1OUT ^= (BIT0 + BIT6); } }
void main(void) { OS_Init(); // OS System init ADC_init(); // Should be done first PWM_init(); // Beware pwm ports go together with ANALOG in setPortBIO(0x04); // Set port B in output mode setPortDIO(0x00); // Set port D in output mode XLCDInit(); // initialize the LCD module XLCDClear(); // Push een kleine lijst //push(2); //push(1); //push(3); OS_Task_Create(0, Task_Server); // BT Connection OS_Task_Create(1, Task_Hartbeat); // Show I am alive (called by scheduler)// OS_Task_Create(1, Task_Run); // Run me through the maze (called by scheduler)// OS_Task_Create(2, Task_Display); // be called by scheduler OS_Run(); // Run scheduler }
/********************************************************************* * @fn SimpleBLEPeripheral_ProcessEvent * * @brief Simple BLE Peripheral Application Task event processor. This function * is called to process all events for the task. Events * include timers, messages and any other user defined events. * * @param task_id - The OSAL assigned task ID. * @param events - events to process. This is a bit map and can * contain more than one event. * * @return events not processed */ uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events ) { //tasksArr[] ÊÇ11¸öTaskµÄ×îºóÒ»¸ö£¬ÓÉOSAL ϵͳ½øÐе÷¶È¡£ÓÐʱ¼äÀ´ÁË£¬Óø÷½·¨´¦Àí¡£³õʼ»¯OSAL_SimpleBLEperipheal VOID task_id; // OSAL required parameter that isn't used in this function if ( events & SYS_EVENT_MSG ) { uint8 *pMsg; if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL ) { simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg ); // Release the OSAL message VOID osal_msg_deallocate( pMsg ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } if ( events & SBP_START_DEVICE_EVT ) { // Start the Device Õâ¸öÊÇÉ豸ÓÐ״̬±ä»¯²Å»áµ÷ÓõĻص÷º¯Êý VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs ); // Start Bond Manager VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs ); // Set timer for first periodic event //init LED PWM_init(); init_QI_Switch(1); //dataChange(1,0); //osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD ); //LedChange(); return ( events ^ SBP_START_DEVICE_EVT ); } if ( events & SBP_PERIODIC_EVT ) { //osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD ); //Ö´ÐеƹâchangeµÄº¯Êý if(P1_1 == 1){ //HalLcdWriteString("HEIGH",HAL_LCD_LINE_4); }else{ //HalLcdWriteString("LOW",HAL_LCD_LINE_4); } LedChange(); return (events ^ SBP_PERIODIC_EVT); } // Discard unknown events return 0; }
void initialize_hardware(){ sysclock_init(); LPC_MRT->Channel[0].CTRL=(1u<<1); //multi-rate timer canal 0 en mode 'one-shot interrupt' assign_pins(); // assignation des périphériques aux broches //LPC_SYSCON->IRQLATENCY=40; NVIC_SetPriority(SCT_IRQn,0); // plus haute priorité d'interruption NVIC_SetPriority(MRT_IRQn,3); // plus basse priorité PWM_init(); SPI0_init(); }//f()
/** * @brief Main program. * @param None * @retval None */ int main(void) { RCC_ClocksTypeDef RCC_Clocks; /* SysTick end of count event each 10ms */ RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); /********************输出 初始化 ******************/ PWM_init(); STM324xG_LCD_Init(); LCD_Clear(BLACK);/* Clear the LCD */ LCD_SetBackColor(BLACK);/* Set the LCD Back Color */ LCD_SetTextColor(WHITE);/* Set the LCD Text Color */ LCD_DisplayStringLine(LINE(0), " Hello jaja. I'm xiaohei01"); /********************输入 初始化 ******************/ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);/*!< 3 bits for pre-emption priority 1 bits for subpriority */ Encoder_init(); //encoder tim8 usart_init();//通信COM usart2 115200 IMU_init(); if (get_mode()==1) { IMU_BE10(); } KEY_init(); AD_Init(); GPS_int(); TIM2_Configuration(); printf("uart init OK 2 \r\n"); while(1) { if(LCD_flag) { LCD_flag=0; lcd_refresh(); } } }
int main(void) { ADC_Config(); PID_init(); PWM_init(405); sei(); while(1) { //TODO:: Please write your application code } cli(); }
int main() { #if defined(PIC32_PINGUINO) || defined(PIC32_PINGUINO_OTG) TRISDbits.TRISD9=1; // because PORTB is shared with SDA on Olimex board TRISDbits.TRISD10=1; // because PORTB is shared with SCL on Olimex board #endif SystemConfig(80000000); // default clock frequency is 80Mhz // default peripheral freq. is 40MHz (cf. system.c) // All pins of PORTB as digital IOs #ifdef __32MX220F032D__ ANSELA = 0; ANSELB = 0; ANSELC = 0; #else AD1PCFG = 0xFFFF; #endif #ifdef __ANALOG__ analog_init(); #endif #ifdef __MILLIS__ millis_init(); #endif #ifdef __PWM__ PWM_init(); #endif #ifdef __USBCDC CDC_init(); #endif #ifdef __RTCC__ RTCC_init(); #endif setup(); while (1) { #ifdef __USBCDC CDCTxService(); #endif loop(); } return(0); }
inline void setup_handles(void){ myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj)); myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj)); myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj)); myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj)); myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj)); myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj)); myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj)); mySci = SCI_init((void *)SCIA_BASE_ADDR, sizeof(SCI_Obj)); myAdc = ADC_init((void *)ADC_BASE_ADDR, sizeof(ADC_Obj)); myPwm1 = PWM_init((void *)PWM_ePWM1_BASE_ADDR, sizeof(PWM_Obj)); }
int main() { // default peripheral freq. is CPUCoreFrequency / 2 (cf. system.c) #if defined(__32MX220F032D__)||defined(__32MX250F128B__)||defined(__32MX220F032B__) SystemConfig(40000000); // default clock frequency is 40Mhz #else SystemConfig(80000000); // default clock frequency is 80Mhz #endif IOsetSpecial(); IOsetDigital(); IOsetRemap(); #ifdef __ANALOG__ analog_init(); #endif #ifdef __MILLIS__ millis_init(); #endif #ifdef __PWM__ PWM_init(); #endif #ifdef __USBCDC CDC_init(); #endif #ifdef __RTCC__ RTCC_init(); #endif setup(); while (1) { #ifdef __USBCDC #if defined(__32MX220F032D__)||defined(__32MX250F128B__)||defined(__32MX220F032B__) USB_Service( ); #else CDCTxService(); #endif #endif loop(); } return(0); }
int main(void) { GPIO_init(); Timer_init(); PWM_init(); ADC_init(); NVIC_init(); // infinite loop while (1) { } }
/* * ======== EK_TM4C123GXL_initPWM ======== */ void EK_TM4C123GXL_initPWM(void) { /* Enable PWM peripherals */ SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); /* * Enable PWM output on GPIO pins. Board_LED1 and Board_LED2 are now * controlled by PWM peripheral - Do not use GPIO APIs. */ GPIOPinConfigure(GPIO_PF2_M1PWM6); GPIOPinConfigure(GPIO_PF3_M1PWM7); GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3); PWM_init(); }
int main(void) { init_gpio(); init_timer_A(); PWM_init(); PWM0->_2_LOAD = 4999; //PWM0->_2_CMPA = 4846; while(1) { sweep_counter_clockwise(); sweep_clockwise(); } }
int main(void){ uint16_t v0,v1,v2; double t0,t1,t2; char t_chr[7]; memset(t_chr, '\0', sizeof(t_chr)); USART_init(MYUBRR); /* Remove garbage from serial terminal */ USART_transmit('\r'); ADC_init(); PWM_init(); while(1){ v0 = ADC_read(0); /* read from ADC0 */ v1 = ADC_read(1); /* read from ADC0 */ v2 = ADC_read(2); /* read from ADC0 */ t0 = v0 / 4; t1 = v1 / 4; t2 = v2 / 4; dtostrf(t0, 5, 1, t_chr); USART_write("0: "); USART_write(t_chr); USART_write("\r\n"); dtostrf(t1, 5, 1, t_chr); USART_write("1: "); USART_write(t_chr); USART_write("\r\n"); dtostrf(t2, 5, 1, t_chr); USART_write("2: "); USART_write(t_chr); USART_write("\r\n"); OCR0A = t0; OCR0B = t1; OCR2A = t2; _delay_ms(500); } return 1; }
int main(void) { char display_string1[] = "*Hello Amigos. Rolling Banner!*"; char display_string2[] = "+-+-+-+-+"; uint8_t i; init_gpio(); // Initialize GPIO init_timer_A(); // Initialize TIMER0->TIMERA as 16-bit, one-shot and counts down init_timer_B(); // Init TIMER0B as 16-bit, periodic and counts down nvic_init(); // Init NVIC for TIMER0B init_pushButton(); // Initialize LCD display LCD_init(); PWM_init(); for(i=0; display_string1[i] != '\0'; i++) { send_data(display_string1[i]); delay_timer(100); // Since screen has enough to display 16 chars per line, if going off line, start shifting screen. if ( i >= 14 ) send_command(0x18); } send_command(0x2); // Return cursor home send_command(0xC0); // Go to line 2 for(i=0; display_string2[i] != '\0'; i++) { send_data(display_string2[i]); delay_timer(100); // Since screen has enough to display 16 chars per line, if going off line, start shifting screen. if ( i >= 14 ) send_command(0x18); } interrupt_timer(scroll_delay); // Interrupt timer handler scrolls the screen //send_command(0x18); // Shift display to the right by 1 //send_command(0x8); // Turn display off //send_command(0xF); // Turn display on, cursor ON, cursor position ON //GPIOF->DATA |= (1UL << 3); //LED ON //GPIOF->DATA &= ~(1UL << 3); //LED OFF while(1) {} }
void main_init(void) { OSC_init(); TRISA = 0b11100111; // SWB,SWG,SWR,Vcap,x,ADCB,ADCG,ADCR TRISB = 0b00000000; // PGD,PGC,x,PWMW,x,PWMB,PWMG,PWMR TRISC = 0b10111010; // RX,TX,D+,D-,Vusb,x,T1OSI,T1OSO ANCON0 = 0b11111000; // AN2,AN1,AN0 is analog ANCON1 = 0b00011111; // all digital INTCON2bits.RBPU = 0; // PORTB Pull-Up Enable timer0_init(8); // ? timer1_init(0, T1OSC); // ? timer3_init(2); // button? RTCC_init(); PWM_init(PR_VALUE); //250 is 3kHz USB_CDC_init(); }
int main(void) { wdt_enable(WDTO_2S); /* Enable watchdog timer 2s */ hardwareInit(); /* Initialize hardware (I/O) */ usbInit(); /* Initialize USB stack processing */ Setup_init(); speed_init(); PWM_init(); KeyScan_init(); switch (Setup_key12LED){ case Setup_key12LED_Always: case Setup_key12LED_OftenOn: PWM_setOutputLevel(0,PWM_TotalLevel); PWM_setOutputLevel(1,PWM_TotalLevel); break; case Setup_key12LED_Never: case Setup_key12LED_OftenOff: PWM_setOutputLevel(0,0); PWM_setOutputLevel(1,0); } sei(); /* Enable global interrupts */ WorkMode_set(WorkMode_Unused); for(;;){ /* Main loop */ wdt_reset(); /* Reset the watchdog */ usbPoll(); if(KeyScan_keyChanged && usbInterruptIsReady()){ KeyScan_keyChanged = 0; buildReport(); usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); }else{ if(TIFR0&(1<<TOV0)){ TIFR0 |= 1<<TOV0; PWM_Generator(); } } } return 0; }
/* * ======== MSP_EXP432P401R_initPWM ======== */ void MSP_EXP432P401R_initPWM(void) { /* Use Port Map on Port2 get Timer outputs on pins with LEDs (2.1, 2.2) */ // const uint8_t portMap [] = { // PM_NONE, PM_TA1CCR1A, PM_TA1CCR2A, PM_NONE, // PM_NONE, PM_NONE, PM_NONE, PM_NONE //}; /* Mapping capture compare registers to Port 2 */ //MAP_PMAP_configurePorts((const uint8_t *) portMap, (0x40005000) - (0x0010), 1, // PMAP_DISABLE_RECONFIGURATION); /* Enable PWM output on GPIO pins */ MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN1 | GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION); PWM_init(); }
int main(void) { init_gpio(); /* Setup Timers */ init_timer_0A(); init_timer_0B(); // Default to theremin on startup turn_on_red_LED(); PWM_init(); init_ADC(); init_nvic(); init_pushButton(); while(1) {} }
// *********************************************************** // Main program // int main(void) { DDRD = 0x30; //4-5-pins output DDRB = 0xFF; // DDRC = 0xFF; // // External interrupt adjustments GICR |= 1 << INT0; //Enable INT0 (PD2) MCUCR &= ~(1 << ISC01); //The low level of INT0 generates an interrupt request. MCUCR &= ~(1 << ISC00); //UART Port speed 115200 for the crystal freq. 7.3MHz USART_init (); ADC_init(); PWM_init(); USART_transmit('c');// Change the directory on USART_transmit('d');//ARM to home. Cannot run USART_transmit(' ');///home/status STATUS__ USART_transmit('/');//need to cd to /home USART_transmit('h'); USART_transmit('o'); USART_transmit('m'); USART_transmit('e'); USART_transmit(0x0A); while(1) { //Check if the status of controller changed then send via UART otherwise don't send if (memcmp ((char *)&PREV_AVR_STATUS, (char *)&AVR_STATUS, sizeof (avr_status)) != 0 ) { send_status(); //after sending the status make the previous status - actual memcpy ((char *)&PREV_AVR_STATUS, (char *)&AVR_STATUS, sizeof (avr_status)); } _delay_us(10); // time which regulate the frequency of checking the status } // Infinite loop }//int main(void)
int main(void) { PWM_init(); CF_init(&alpha, &beta); PID_init(&pid_x, &pid_y); Flags_init(); Timer1_init(); Twi_init(); Usart_init(); deviceInit_adc(); deviceInit_rc(); if(!deviceInit() || !Flags_getBit(flags_deviceAdcInitialised) || !Flags_getBit(flags_deviceRcInitialised)) { _exit(); } // todo: workaround for slave initialization deviceInitialize(deviceID_slave, _true); // todo: workaround for gps initialization deviceInitialize(deviceID_gps, _true); //enable interrupts _enableInterrupts(); while(1); }
int main(void) { uint16_t send_status_timeout = 25; uint32_t pos; uint8_t button_state = 0; uint8_t manual_dim_direction = 0; // delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms... _delay_ms(1000); util_init(); check_eeprom_compatibility(DEVICETYPE_DIMMER); // read packetcounter, increase by cycle and write back packetcounter = e2p_generic_get_packetcounter() + PACKET_COUNTER_WRITE_CYCLE; e2p_generic_set_packetcounter(packetcounter); // read device id device_id = e2p_generic_get_deviceid(); // pwm translation table is not used if first byte is 0xFF use_pwm_translation = (0xFF != eeprom_read_UIntValue8(EEPROM_BRIGHTNESSTRANSLATIONTABLE_BYTE, EEPROM_BRIGHTNESSTRANSLATIONTABLE_BIT, 8, 0, 0xFF)); // TODO: read (saved) dimmer state from before the eventual powerloss /*for (i = 0; i < SWITCH_COUNT; i++) { uint16_t u16 = eeprom_read_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2); switch_state[i] = (uint8_t)(u16 & 0b1); switch_timeout[i] = u16 >> 1; }*/ // read last received station packetcounter station_packetcounter = e2p_dimmer_get_basestationpacketcounter(); led_blink(500, 500, 3); osccal_init(); uart_init(); UART_PUTS ("\r\n"); UART_PUTF4("smarthomatic Dimmer v%u.%u.%u (%08lx)\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_HASH); UART_PUTS("(c) 2013..2014 Uwe Freese, www.smarthomatic.org\r\n"); osccal_info(); UART_PUTF ("DeviceID: %u\r\n", device_id); UART_PUTF ("PacketCounter: %lu\r\n", packetcounter); UART_PUTF ("Use PWM translation table: %u\r\n", use_pwm_translation); UART_PUTF ("Last received base station PacketCounter: %u\r\n\r\n", station_packetcounter); // init AES key eeprom_read_block (aes_key, (uint8_t *)EEPROM_AESKEY_BYTE, 32); rfm12_init(); PWM_init(); io_init(); setPWMDutyCyclePercent(0); timer0_init(); // DEMO to measure the voltages of different PWM settings to calculate the pwm_lookup table /*while (42) { uint16_t i; for (i = 0; i <= 1024; i = i + 100) { UART_PUTF ("PWM value OCR1A: %u\r\n", i); OCR1A = i; led_blink(500, 6500, 1); } }*/ // DEMO 0..100..0%, using the pwm_lookup table and the translation table in EEPROM. /*while (42) { float i; for (i = 0; i <= 100; i = i + 0.05) { led_blink(10, 10, 1); setPWMDutyCycle(i); } for (i = 99.95; i > 0; i = i - 0.05) { led_blink(10, 10, 1); setPWMDutyCycle(i); } }*/ // set initial switch state /*for (i = 0; i < SWITCH_COUNT; i++) { switchRelais(i, switch_state[i]); }*/ sei(); // DEMO 30s /*animation_length = 30; animation_length = (uint32_t)((float)animation_length * 1000 / ANIMATION_CYCLE_MS); start_brightness = 0; end_brightness = 255; animation_position = 0;*/ while (42) { if (rfm12_rx_status() == STATUS_COMPLETE) { uint8_t len = rfm12_rx_len(); if ((len == 0) || (len % 16 != 0)) { UART_PUTF("Received garbage (%u bytes not multiple of 16): ", len); print_bytearray(bufx, len); } else // try to decrypt with all keys stored in EEPROM { memcpy(bufx, rfm12_rx_buffer(), len); UART_PUTS("Before decryption: "); print_bytearray(bufx, len); aes256_decrypt_cbc(bufx, len); UART_PUTS("Decrypted bytes: "); print_bytearray(bufx, len); if (!pkg_header_check_crc32(len)) { UART_PUTS("Received garbage (CRC wrong after decryption).\r\n"); } else { process_packet(len); } } // tell the implementation that the buffer can be reused for the next data. rfm12_rx_clear(); } _delay_ms(ANIMATION_UPDATE_MS); // React on button press. // - abort animation // - switch off, when brightness > 0 // - switch on otherwise if (!(BUTTON_PORT & (1 << BUTTON_PIN))) // button press { if (button_state == 0) { UART_PUTS("Button pressed\r\n"); animation_length = 0; animation_position = 0; } if (button_state < 5) { button_state++; } else // manual dimming { if (manual_dim_direction) // UP { if (current_brightness < 100) { current_brightness = (uint8_t)current_brightness / 2 * 2 + 2; setPWMDutyCyclePercent(current_brightness); } else { UART_PUTS("manual dimming DOWN\r\n"); manual_dim_direction = 0; } } else // DOWN { if (current_brightness > 0) { current_brightness = (((uint8_t)current_brightness - 1) / 2) * 2; setPWMDutyCyclePercent(current_brightness); } else { UART_PUTS("manual dimming UP\r\n"); manual_dim_direction = 1; } } } } else if (button_state && (BUTTON_PORT & (1 << BUTTON_PIN))) // button release { UART_PUTS("Button released\r\n"); if (button_state < 5) // short button press { if (current_brightness > 0) { UART_PUTS(" -> 0%\r\n"); setPWMDutyCyclePercent(0); } else { UART_PUTS(" -> 100%\r\n"); setPWMDutyCyclePercent(100); } } else { // reverse dim direction manual_dim_direction = !manual_dim_direction; } button_state = 0; } // update brightness according animation_position, updated by timer0 if (animation_length > 0) { pos = animation_position; // copy value to avoid that it changes in between by timer interrupt UART_PUTF2("%lu/%lu, ", pos, animation_length); if (pos == animation_length) { UART_PUTF("END Brightness %u%%, ", end_brightness); setPWMDutyCyclePercent((float)end_brightness); animation_length = 0; animation_position = 0; } else { float brightness = (start_brightness + ((float)end_brightness - start_brightness) * pos / animation_length); UART_PUTF("Br.%u%%, ", (uint32_t)(brightness)); setPWMDutyCyclePercent(brightness); } } // send status from time to time if (send_status_timeout == 0) { send_status_timeout = SEND_STATUS_EVERY_SEC * (1000 / ANIMATION_UPDATE_MS); send_dimmer_status(); led_blink(200, 0, 1); } else if (version_status_cycle >= SEND_VERSION_STATUS_CYCLE) { version_status_cycle = 0; send_version_status(); led_blink(200, 0, 1); } rfm12_tick(); send_status_timeout--; checkSwitchOff(); } // never called // aes256_done(&aes_ctx); }
/* * ======== Board_initPWM ======== */ void Board_initPWM(void) { PWM_init(); }
void stage4() { PWM_init(); }
void main(void) { CPU_Handle myCpu; PLL_Handle myPll; WDOG_Handle myWDog; // Initialize all the handles needed for this application myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj)); myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj)); myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj)); myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj)); myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj)); myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj)); myPwm1 = PWM_init((void *)PWM_ePWM1_BASE_ADDR, sizeof(PWM_Obj)); myPwm2 = PWM_init((void *)PWM_ePWM2_BASE_ADDR, sizeof(PWM_Obj)); myPwm3 = PWM_init((void *)PWM_ePWM3_BASE_ADDR, sizeof(PWM_Obj)); myPwm4 = PWM_init((void *)PWM_ePWM4_BASE_ADDR, sizeof(PWM_Obj)); myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj)); // Perform basic system initialization WDOG_disable(myWDog); CLK_enableAdcClock(myClk); (*Device_cal)(); CLK_disableAdcClock(myClk); //Select the internal oscillator 1 as the clock source CLK_setOscSrc(myClk, CLK_OscSrc_Internal); // Setup the PLL for x12 /2 which will yield 60Mhz = 10Mhz * 12 / 2 PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2); // Disable the PIE and all interrupts PIE_disable(myPie); PIE_disableAllInts(myPie); CPU_disableGlobalInts(myCpu); CPU_clearIntFlags(myCpu); // If running from flash copy RAM only functions to RAM #ifdef _FLASH memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); #endif // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the f2802x_SysCtrl.c file. // InitSysCtrl(); // Step 2. Initialize GPIO: // This example function is found in the f2802x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Skipped for this example // InitEPwmGpio(); // Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interrupts // DINT; // Initialize the PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared. // This function is found in the f2802x_PieCtrl.c file. // InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags: // IER = 0x0000; // IFR = 0x0000; // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in f2802x_DefaultIsr.c. // This function is found in f2802x_PieVect.c. // InitPieVectTable(); // For this case just init GPIO pins for EPwm1, EPwm2, EPwm3, EPwm4 GPIO_setPullUp(myGpio, GPIO_Number_0, GPIO_PullUp_Disable); GPIO_setPullUp(myGpio, GPIO_Number_1, GPIO_PullUp_Disable); GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_EPWM1A); GPIO_setMode(myGpio, GPIO_Number_1, GPIO_1_Mode_EPWM1B); GPIO_setPullUp(myGpio, GPIO_Number_2, GPIO_PullUp_Disable); GPIO_setPullUp(myGpio, GPIO_Number_3, GPIO_PullUp_Disable); GPIO_setMode(myGpio, GPIO_Number_2, GPIO_2_Mode_EPWM2A); GPIO_setMode(myGpio, GPIO_Number_3, GPIO_3_Mode_EPWM2B); GPIO_setPullUp(myGpio, GPIO_Number_4, GPIO_PullUp_Disable); GPIO_setPullUp(myGpio, GPIO_Number_5, GPIO_PullUp_Disable); GPIO_setMode(myGpio, GPIO_Number_4, GPIO_4_Mode_EPWM3A); GPIO_setMode(myGpio, GPIO_Number_5, GPIO_5_Mode_EPWM3B); GPIO_setPullUp(myGpio, GPIO_Number_6, GPIO_PullUp_Disable); GPIO_setPullUp(myGpio, GPIO_Number_7, GPIO_PullUp_Disable); GPIO_setMode(myGpio, GPIO_Number_6, GPIO_6_Mode_EPWM4A); GPIO_setMode(myGpio, GPIO_Number_7, GPIO_7_Mode_EPWM4B); // Setup a debug vector table and enable the PIE PIE_setDebugIntVectorTable(myPie); PIE_enable(myPie); CLK_enablePwmClock(myClk, PWM_Number_1); CLK_enablePwmClock(myClk, PWM_Number_2); CLK_enablePwmClock(myClk, PWM_Number_3); CLK_enablePwmClock(myClk, PWM_Number_4); CLK_enableHrPwmClock(myClk); // For this example, only initialize the ePWM // Step 4. User specific code, enable interrupts: UpdateFine = 1; PeriodFine = 0; status = SFO_INCOMPLETE; // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor. // HRMSTEP must be populated with a scale factor value prior to enabling // high resolution period control. while (status== SFO_INCOMPLETE) // Call until complete { status = SFO(); if (status == SFO_ERROR) { error(); // SFO function returns 2 if an error occurs & # of MEP steps/coarse step } // exceeds maximum of 255. } // Some useful Period vs Frequency values // SYSCLKOUT = 60 MHz 40 MHz // -------------------------------------- // Period Frequency Frequency // 1000 60 kHz 40 kHz // 800 75 kHz 50 kHz // 600 100 kHz 67 kHz // 500 120 kHz 80 kHz // 250 240 kHz 160 kHz // 200 300 kHz 200 kHz // 100 600 kHz 400 kHz // 50 1.2 Mhz 800 kHz // 25 2.4 Mhz 1.6 MHz // 20 3.0 Mhz 2.0 MHz // 12 5.0 MHz 3.3 MHz // 10 6.0 MHz 4.0 MHz // 9 6.7 MHz 4.4 MHz // 8 7.5 MHz 5.0 MHz // 7 8.6 MHz 5.7 MHz // 6 10.0 MHz 6.6 MHz // 5 12.0 MHz 8.0 MHz //==================================================================== // ePWM and HRPWM register initialization //==================================================================== CLK_disableTbClockSync(myClk); HRPWM_Config(myPwm1, 30); // ePWMx target HRPWM_Config(myPwm2, 30); // ePWMx target HRPWM_Config(myPwm3, 30); // ePWMx target HRPWM_Config(myPwm4, 30); // ePWMx target CLK_enableTbClockSync(myClk); PWM_forceSync(myPwm1); PWM_forceSync(myPwm2); PWM_forceSync(myPwm3); PWM_forceSync(myPwm4); for(;;) { // Sweep PeriodFine as a Q16 number from 0.2 - 0.999 for(PeriodFine = 0x3333; PeriodFine < 0xFFBF; PeriodFine++) { if(UpdateFine) { /* // Because auto-conversion is enabled, the desired // fractional period must be written directly to the // TBPRDHR (or TBPRDHRM) register in Q16 format // (lower 8-bits are ignored) EPwm1Regs.TBPRDHR = PeriodFine; // The hardware will automatically scale // the fractional period by the MEP_ScaleFactor // in the HRMSTEP register (which is updated // by the SFO calibration software). // Hardware conversion: // MEP delay movement = ((TBPRDHR(15:0) >> 8) * HRMSTEP(7:0) + 0x80) >> 8 */ // for(i=1;i<PWM_CH;i++) // { // (*ePWM[i]).TBPRDHR = PeriodFine; //In Q16 format // } PWM_setPeriodHr(myPwm1, PeriodFine); PWM_setPeriodHr(myPwm2, PeriodFine); PWM_setPeriodHr(myPwm3, PeriodFine); PWM_setPeriodHr(myPwm4, PeriodFine); } else { // No high-resolution movement on TBPRDHR. // for(i=1;i<PWM_CH;i++) // { // (*ePWM[i]).TBPRDHR = 0; // } PWM_setPeriodHr(myPwm1, 0); PWM_setPeriodHr(myPwm2, 0); PWM_setPeriodHr(myPwm3, 0); PWM_setPeriodHr(myPwm4, 0); } // Call the scale factor optimizer lib function SFO() // periodically to track for any change due to temp/voltage. // This function generates MEP_ScaleFactor by running the // MEP calibration module in the HRPWM logic. This scale // factor can be used for all HRPWM channels. HRMSTEP // register is automatically updated by the SFO function. status = SFO(); // in background, MEP calibration module continuously updates MEP_ScaleFactor if (status == SFO_ERROR) { error(); // SFO function returns 2 if an error occurs & # of MEP steps/coarse step } // exceeds maximum of 255. } // end PeriodFine for loop } // end infinite for loop } // end main
void main(void) { CPU_Handle myCpu; PLL_Handle myPll; WDOG_Handle myWDog; // Initialize all the handles needed for this application myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj)); myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj)); myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj)); myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj)); myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj)); myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj)); myPwm1 = PWM_init((void *)PWM_ePWM1_BASE_ADDR, sizeof(PWM_Obj)); myPwm2 = PWM_init((void *)PWM_ePWM2_BASE_ADDR, sizeof(PWM_Obj)); myPwm3 = PWM_init((void *)PWM_ePWM3_BASE_ADDR, sizeof(PWM_Obj)); myPwm4 = PWM_init((void *)PWM_ePWM4_BASE_ADDR, sizeof(PWM_Obj)); myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj)); // Perform basic system initialization WDOG_disable(myWDog); CLK_enableAdcClock(myClk); (*Device_cal)(); CLK_disableAdcClock(myClk); //Select the internal oscillator 1 as the clock source CLK_setOscSrc(myClk, CLK_OscSrc_Internal); // Setup the PLL for x12 /2 which will yield 60Mhz = 10Mhz * 12 / 2 PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2); // Disable the PIE and all interrupts PIE_disable(myPie); PIE_disableAllInts(myPie); CPU_disableGlobalInts(myCpu); CPU_clearIntFlags(myCpu); // If running from flash copy RAM only functions to RAM #ifdef _FLASH memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); #endif // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the f2802x_SysCtrl.c file. // InitSysCtrl(); // Step 2. Initialize GPIO: // This example function is found in the f2802x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Skipped for this example // InitEPwmGpio(); // Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interrupts // DINT; // Initialize the PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared. // This function is found in the f2802x_PieCtrl.c file. // InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags: // IER = 0x0000; // IFR = 0x0000; // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in f2802x_DefaultIsr.c. // This function is found in f2802x_PieVect.c. // InitPieVectTable(); // For this case just init GPIO pins for EPwm1, EPwm2, EPwm3, EPwm4 GPIO_setPullUp(myGpio, GPIO_Number_0, GPIO_PullUp_Disable); GPIO_setPullUp(myGpio, GPIO_Number_1, GPIO_PullUp_Disable); GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_EPWM1A); GPIO_setMode(myGpio, GPIO_Number_1, GPIO_1_Mode_EPWM1B); GPIO_setPullUp(myGpio, GPIO_Number_2, GPIO_PullUp_Disable); GPIO_setPullUp(myGpio, GPIO_Number_3, GPIO_PullUp_Disable); GPIO_setMode(myGpio, GPIO_Number_2, GPIO_2_Mode_EPWM2A); GPIO_setMode(myGpio, GPIO_Number_3, GPIO_3_Mode_EPWM2B); GPIO_setPullUp(myGpio, GPIO_Number_4, GPIO_PullUp_Disable); GPIO_setPullUp(myGpio, GPIO_Number_5, GPIO_PullUp_Disable); GPIO_setMode(myGpio, GPIO_Number_4, GPIO_4_Mode_EPWM3A); GPIO_setMode(myGpio, GPIO_Number_5, GPIO_5_Mode_EPWM3B); GPIO_setPullUp(myGpio, GPIO_Number_6, GPIO_PullUp_Disable); GPIO_setPullUp(myGpio, GPIO_Number_7, GPIO_PullUp_Disable); GPIO_setMode(myGpio, GPIO_Number_6, GPIO_6_Mode_EPWM4A); GPIO_setMode(myGpio, GPIO_Number_7, GPIO_7_Mode_EPWM4B); // Setup a debug vector table and enable the PIE PIE_setDebugIntVectorTable(myPie); PIE_enable(myPie); // Step 4. Initialize the Device Peripherals: CLK_enablePwmClock(myClk, PWM_Number_1); CLK_enablePwmClock(myClk, PWM_Number_2); CLK_enablePwmClock(myClk, PWM_Number_3); CLK_enablePwmClock(myClk, PWM_Number_4); CLK_enableHrPwmClock(myClk); // For this example, only initialize the ePWM // Step 5. User specific code, enable interrupts: // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor. // HRMSTEP must be populated with a scale factor value prior to enabling // high resolution period control. status = SFO_INCOMPLETE; while (status== SFO_INCOMPLETE) // Call until complete { status = SFO(); if (status == SFO_ERROR) { error(); // SFO function returns 2 if an error occurs & # of MEP steps/coarse step } // exceeds maximum of 255. } // Some useful PWM period vs Frequency values // TBCLK = 60 MHz //=================== // Period Freq // 1000 30 KHz // 800 37.5 KHz // 600 50 KHz // 500 60 KHz // 250 120 KHz // 200 150 KHz // 100 300 KHz // 50 600 KHz // 30 1 MHz // 25 1.2 MHz // 20 1.5 MHz // 12 2.5 MHz // 10 3 MHz // 9 3.3 MHz // 8 3.8 MHz // 7 4.3 MHz // 6 5.0 MHz // 5 6.0 MHz //==================================================================== // ePWM and HRPWM register initialization //==================================================================== Period = 500; PeriodFine=0xFFBF; CLK_disableTbClockSync(myClk); HRPWM_Config(myPwm1, Period, 1); HRPWM_Config(myPwm2, Period, 0); HRPWM_Config(myPwm3, Period, 0); HRPWM_Config(myPwm4, Period, 0); CLK_enableTbClockSync(myClk); // Software Control variables Increment_Freq = 1; Increment_Freq_Fine = 1; IsrTicker = 0; UpdatePeriod = 0; UpdatePeriodFine = 0; // User control variables: UpdateCoarse = 0; UpdateFine = 1; // Reassign ISRs. PIE_registerPieIntHandler(myPie, PIE_GroupNumber_3, PIE_SubGroupNumber_1, (intVec_t)&MainISR); // Enable PIE group 3 interrupt 1 for EPWM1_INT PIE_enableInt(myPie, PIE_GroupNumber_3, PIE_InterruptSource_EPWM1); // Enable CNT_zero interrupt using EPWM1 Time-base PWM_setIntMode(myPwm1, PWM_IntMode_CounterEqualZero); // Select INT on Zero event PWM_enableInt(myPwm1); // Enable INT PWM_setIntPeriod(myPwm1, PWM_IntPeriod_FirstEvent); // Generate INT on 3rd event PWM_clearIntFlag(myPwm1); // Enable CPU INT3 for EPWM1_INT: CPU_enableInt(myCpu, CPU_IntNumber_3); // Enable global Interrupts and higher priority real-time debug events: CPU_enableGlobalInts(myCpu); CPU_enableDebugInt(myCpu); PWM_forceSync(myPwm1); // Synchronize high resolution phase to start HR period for(;;) { // The below code controls coarse edge movement if(UpdateCoarse==1) { if(Increment_Freq==1) //Increase frequency to 600 kHz Period= Period - 1; else Period= Period + 1; //Decrease frequency to 300 kHz if(Period<100 && Increment_Freq==1) Increment_Freq=0; else if(Period>500 && Increment_Freq==0) Increment_Freq=1; UpdatePeriod=1; } // The below code controls high-resolution fine edge movement if(UpdateFine==1) { if(Increment_Freq_Fine==1) // Increase high-resolution frequency PeriodFine=PeriodFine-1; else PeriodFine=PeriodFine+1; // Decrement high-resolution frequency if(PeriodFine<=0x3333 && Increment_Freq_Fine==1) Increment_Freq_Fine=0; else if(PeriodFine>= 0xFFBF && Increment_Freq_Fine==0) Increment_Freq_Fine=1; UpdatePeriodFine=1; } // Call the scale factor optimizer lib function SFO() // periodically to track for any change due to temp/voltage. // This function generates MEP_ScaleFactor by running the // MEP calibration module in the HRPWM logic. This scale // factor can be used for all HRPWM channels. HRMSTEP // register is automatically updated by the SFO function. status = SFO(); // in background, MEP calibration module continuously updates MEP_ScaleFactor if (status == SFO_ERROR) { error(); // SFO function returns 2 if an error occurs & # of MEP steps/coarse step } // exceeds maximum of 255. } }// end main
int main(void) { uint16_t send_status_timeout = 25; uint32_t station_packetcounter; uint32_t pos; uint8_t button_state = 0; uint8_t manual_dim_direction = 0; // delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms... _delay_ms(1000); util_init(); check_eeprom_compatibility(DEVICE_TYPE_DIMMER); osccal_init(); // read packetcounter, increase by cycle and write back packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER) + PACKET_COUNTER_WRITE_CYCLE; eeprom_write_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER, packetcounter); // read device id and write to send buffer device_id = eeprom_read_byte((uint8_t*)EEPROM_POS_DEVICE_ID); use_pwm_translation = 1; //eeprom_read_byte((uint8_t*)EEPROM_POS_USE_PWM_TRANSLATION); // TODO: read (saved) dimmer state from before the eventual powerloss /*for (i = 0; i < SWITCH_COUNT; i++) { uint16_t u16 = eeprom_read_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2); switch_state[i] = (uint8_t)(u16 & 0b1); switch_timeout[i] = u16 >> 1; }*/ // read last received station packetcounter station_packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_STATION_PACKET_COUNTER); led_blink(200, 200, 5); #ifdef UART_DEBUG uart_init(false); UART_PUTS ("\r\n"); UART_PUTS ("smarthomatic Dimmer V1.0 (c) 2013 Uwe Freese, www.smarthomatic.org\r\n"); osccal_info(); UART_PUTF ("Device ID: %u\r\n", device_id); UART_PUTF ("Packet counter: %lu\r\n", packetcounter); UART_PUTF ("Use PWM translation table: %u\r\n", use_pwm_translation); UART_PUTF ("Last received station packet counter: %u\r\n\r\n", station_packetcounter); #endif // init AES key eeprom_read_block (aes_key, (uint8_t *)EEPROM_POS_AES_KEY, 32); rfm12_init(); PWM_init(); io_init(); setPWMDutyCycle(0); timer0_init(); // DEMO to measure the voltages of different PWM settings to calculate the pwm_lookup table /*while (42) { uint16_t i; for (i = 0; i <= 1024; i = i + 100) { UART_PUTF ("PWM value OCR1A: %u\r\n", i); OCR1A = i; led_blink(500, 6500, 1); } }*/ // DEMO 0..100..0%, using the pwm_lookup table and the translation table in EEPROM. /*while (42) { float i; for (i = 0; i <= 100; i = i + 0.05) { led_blink(10, 10, 1); setPWMDutyCycle(i); } for (i = 99.95; i > 0; i = i - 0.05) { led_blink(10, 10, 1); setPWMDutyCycle(i); } }*/ // set initial switch state /*for (i = 0; i < SWITCH_COUNT; i++) { switchRelais(i, switch_state[i]); }*/ sei(); // DEMO 30s /*animation_length = 30; animation_length = (uint32_t)((float)animation_length * 1000 / ANIMATION_CYCLE_MS); start_brightness = 0; end_brightness = 255; animation_position = 0;*/ while (42) { if (rfm12_rx_status() == STATUS_COMPLETE) { uint8_t len = rfm12_rx_len(); if ((len == 0) || (len % 16 != 0)) { UART_PUTF("Received garbage (%u bytes not multiple of 16): ", len); printbytearray(bufx, len); } else // try to decrypt with all keys stored in EEPROM { memcpy(bufx, rfm12_rx_buffer(), len); //UART_PUTS("Before decryption: "); //printbytearray(bufx, len); aes256_decrypt_cbc(bufx, len); //UART_PUTS("Decrypted bytes: "); //printbytearray(bufx, len); uint32_t assumed_crc = getBuf32(len - 4); uint32_t actual_crc = crc32(bufx, len - 4); //UART_PUTF("Received CRC32 would be %lx\r\n", assumed_crc); //UART_PUTF("Re-calculated CRC32 is %lx\r\n", actual_crc); if (assumed_crc != actual_crc) { UART_PUTS("Received garbage (CRC wrong after decryption).\r\n"); } else { //UART_PUTS("CRC correct, AES key found!\r\n"); UART_PUTS(" Received: "); printbytearray(bufx, len - 4); // decode command and react uint8_t sender = bufx[0]; UART_PUTF(" Sender: %u\r\n", sender); if (sender != 0) { UART_PUTF("Packet not from base station. Ignoring (Sender ID was: %u).\r\n", sender); } else { uint32_t packcnt = getBuf32(1); UART_PUTF(" Packet Counter: %lu\r\n", packcnt); // check received counter if (0) //packcnt <= station_packetcounter) { UART_PUTF2("Received packet counter %lu is lower than last received counter %lu. Ignoring packet.\r\n", packcnt, station_packetcounter); } else { // write received counter station_packetcounter = packcnt; eeprom_write_dword((uint32_t*)EEPROM_POS_STATION_PACKET_COUNTER, station_packetcounter); // check command ID uint8_t cmd = bufx[5]; UART_PUTF(" Command ID: %u\r\n", cmd); if (cmd != 141) // ID 141 == Dimmer Request { UART_PUTF("Received unknown command ID %u. Ignoring packet.\r\n", cmd); } else { // check device id uint8_t rcv_id = bufx[6]; UART_PUTF(" Receiver ID: %u\r\n", rcv_id); if (rcv_id != device_id) { UART_PUTF("Device ID %u does not match. Ignoring packet.\r\n", rcv_id); } else { // read animation mode and parameters uint8_t animation_mode = bufx[7] >> 5; // TODO: Implement support for multiple dimmers (e.g. RGB) // uint8_t dimmer_bitmask = bufx[7] & 0b111; animation_length = getBuf16(8); start_brightness = bufx[10]; end_brightness = bufx[11]; UART_PUTF(" Animation Mode: %u\r\n", animation_mode); // TODO: Set binary mode like 00010110 //UART_PUTF(" Dimmer Bitmask: %u\r\n", dimmer_bitmask); UART_PUTF(" Animation Time: %us\r\n", animation_length); UART_PUTF(" Start Brightness: %u\r\n", start_brightness); UART_PUTF(" End Brightness: %u\r\n", end_brightness); animation_length = (uint32_t)((float)animation_length * 1000 / ANIMATION_CYCLE_MS); animation_position = 0; /* TODO: Write to EEPROM (?) // write back switch state to EEPROM switch_state[i] = req_state; switch_timeout[i] = req_timeout; eeprom_write_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2, u16); */ // send acknowledge UART_PUTS("Sending ACK:\r\n"); // set device ID (base station has ID 0 by definition) bufx[0] = device_id; // update packet counter packetcounter++; if (packetcounter % PACKET_COUNTER_WRITE_CYCLE == 0) { eeprom_write_dword((uint32_t*)0, packetcounter); } setBuf32(1, packetcounter); // set command ID "Generic Acknowledge" bufx[5] = 1; // set sender ID of request bufx[6] = sender; // set Packet counter of request setBuf32(7, station_packetcounter); // zero unused bytes bufx[11] = 0; // set CRC32 uint32_t crc = crc32(bufx, 12); setBuf32(12, crc); // show info UART_PUTF(" CRC32: %lx\r\n", crc); uart_putstr(" Unencrypted: "); printbytearray(bufx, 16); rfm12_sendbuf(); UART_PUTS(" Send encrypted: "); printbytearray(bufx, 16); UART_PUTS("\r\n"); rfm12_tick(); led_blink(200, 0, 1); send_status_timeout = 25; } } } } } } // tell the implementation that the buffer can be reused for the next data. rfm12_rx_clear(); } _delay_ms(ANIMATION_UPDATE_MS); // React on button press. // - abort animation // - switch off, when brightness > 0 // - switch on otherwise if (!(BUTTON_PORT & (1 << BUTTON_PIN))) // button press { if (button_state == 0) { UART_PUTS("Button pressed\r\n"); animation_length = 0; animation_position = 0; } if (button_state < 5) { button_state++; } else // manual dimming { if (manual_dim_direction) // UP { if (current_brightness < 100) { current_brightness = (uint8_t)current_brightness / 2 * 2 + 2; setPWMDutyCycle(current_brightness); } else { UART_PUTS("manual dimming DOWN\r\n"); manual_dim_direction = 0; } } else // DOWN { if (current_brightness > 0) { current_brightness = (((uint8_t)current_brightness - 1) / 2) * 2; setPWMDutyCycle(current_brightness); } else { UART_PUTS("manual dimming UP\r\n"); manual_dim_direction = 1; } } } } else if (button_state && (BUTTON_PORT & (1 << BUTTON_PIN))) // button release { UART_PUTS("Button released\r\n"); if (button_state < 5) // short button press { if (current_brightness > 0) { UART_PUTS(" -> 0%\r\n"); setPWMDutyCycle(0); } else { UART_PUTS(" -> 100%\r\n"); setPWMDutyCycle(100); } } else { // reverse dim direction manual_dim_direction = !manual_dim_direction; } button_state = 0; } // update brightness according animation_position, updated by timer0 if (animation_length > 0) { pos = animation_position; // copy value to avoid that it changes in between by timer interrupt UART_PUTF2("%lu/%lu, ", pos, animation_length); if (pos == animation_length) { UART_PUTF("END Brightness %u%%, ", end_brightness * 100 / 255); setPWMDutyCycle((float)end_brightness * 100 / 255); animation_length = 0; animation_position = 0; } else { float brightness = (start_brightness + ((float)end_brightness - start_brightness) * pos / animation_length) * 100 / 255; UART_PUTF("Br.%u%%, ", (uint32_t)(brightness)); setPWMDutyCycle(brightness); } } // send status from time to time if (send_status_timeout == 0) { send_status_timeout = SEND_STATUS_EVERY_SEC * (1000 / ANIMATION_UPDATE_MS); send_dimmer_status(); led_blink(200, 0, 1); } rfm12_tick(); send_status_timeout--; checkSwitchOff(); }