static bool TurnRight(int fwdPulse,int avrSpeedLeft,int avrSpeedRight,int turnPulse, int resetEnc) { static int vt,vp; LED1_OFF();LED2_OFF();LED3_ON(); switch (CtrlStep) { case 1: posLeftTmp=qei_getPosLeft(); CtrlStep=2; vt=1; vp=1; avrSpeedTmp=avrSpeed; case 2://go straight if ((abs(qei_getPosLeft()-posLeftTmp)<fwdPulse) || (isWallFrontLeft && isWallFrontRight && (IR_GetIrDetectorValue(3)>IR_get_calib_value(IR_CALIB_BASE_FRONT_RIGHT))&& (IR_GetIrDetectorValue(0)>IR_get_calib_value(IR_CALIB_BASE_FRONT_LEFT)))) { if (qei_getPosLeft()<fwdPulse+posLeftTmp) avrSpeed = ((abs(fwdPulse + posLeftTmp - qei_getPosLeft()) / (fwdPulse / avrSpeedTmp)) / 2) + (abs(avrSpeedLeft) + abs(avrSpeedRight)) / 2; else avrSpeed = (abs(avrSpeedLeft) + abs(avrSpeedRight)) / 2; if (isWallLeft) pid_wallfollow(leftError,rightError,avrSpeed,WALL_FOLLOW_LEFT); else { speed_set(MOTOR_RIGHT, avrSpeed); speed_set(MOTOR_LEFT, avrSpeed); } } else { #ifdef TEST_TURNRIGHT_MOVE1 speed_Enable_Hbridge(false); #endif pid_reset(&pid_wall_left); pid_reset(&pid_wall_right); forwardUpdate(); CtrlStep++; avrSpeed=avrSpeedTmp; } break; case 3: posLeftTmp=qei_getPosLeft(); posRightTmp=qei_getPosRight(); CtrlStep++; case 4://turn 90 degree if (abs(qei_getPosLeft()-posLeftTmp) + abs(qei_getPosRight()-posRightTmp) < turnPulse) { speed_set(MOTOR_LEFT, avrSpeedLeft); speed_set(MOTOR_RIGHT, -avrSpeedRight); if((abs(qei_getPosLeft()-posLeftTmp)>(turnPulse*0.8*vp/8)) && (vp<9)) { if (avrSpeedLeft>=24) avrSpeedLeft-=24; vp++; } if((abs(qei_getPosRight()-posRightTmp)>(turnPulse*0.2*vt/8)) && (vt<9)) { if (avrSpeedRight>=4) avrSpeedRight-=4; vt++; } } else { #ifdef TEST_TURNRIGHT_TURN speed_Enable_Hbridge(false); #endif currentDir=(currentDir+1)%4; clearPosition(); qei_setPosLeft(resetEnc); qei_setPosRight(resetEnc); forwardUpdate(); CtrlStep=1; pid_reset(&pid_wall_right); pid_reset(&pid_wall_left); speed_set(MOTOR_LEFT, avrSpeed); speed_set(MOTOR_RIGHT, avrSpeed); return true; } break; } return false; }
void i2c_setbitrate(struct i2c_periph *periph, int bitrate) { // If NOT Busy if (i2c_idle(periph)) { volatile int devider; volatile int risetime; uint32_t i2c = (uint32_t) periph->reg_addr; /***************************************************** Bitrate: -CR2 + CCR + TRISE registers -only change when PE=0 e.g. 10kHz: 36MHz + Standard 0x708 + 0x25 70kHz: 36MHz + Standard 0x101 + 400kHz: 36MHz + Fast 0x1E + 0xb // 1) Program peripheral input clock CR2: to get correct timings // 2) Configure clock control registers // 3) Configure rise time register ******************************************************/ if (bitrate < 3000) bitrate = 3000; // rcc_ppre1_frequency is normally configured to max: 36MHz on F1 and 42MHz on F4 // in fast mode: 2counts low 1 count high -> / 3: // in standard mode: 1 count low, 1 count high -> /2: devider = (rcc_ppre1_frequency/2000) / (bitrate/1000); // never allow faster than 600kbps if (devider < 20) devider = 20; // no overflow either if (devider >=4095) devider = 4095; // risetime can be up to 1/6th of the period risetime = 1000000 / (bitrate/1000) / 6 / 28; if (risetime < 10) risetime = 10; // more will overflow the register: for more you should lower the FREQ if (risetime >=31) risetime = 31; // we do not expect an interrupt as the interface should have been idle, but just in case... __disable_irq(); // this code is in user space: // CCR can only be written when PE is disabled // p731 note 5 i2c_peripheral_disable(i2c); // 1) #ifdef STM32F1 i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_36MHZ); #else // STM32F4 i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_42MHZ); #endif // 2) //i2c_set_fast_mode(i2c); i2c_set_ccr(i2c, devider); // 3) i2c_set_trise(i2c, risetime); // Re-Enable i2c_peripheral_enable(i2c); __enable_irq(); #ifdef I2C_DEBUG_LED __disable_irq(); // this code is in user space: LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); __enable_irq(); #endif } }
int board_early_init_f(void) { unsigned long sdrreg; /* * Enable GPIO for pins 18 - 24 * 18 = SEEPROM_WP * 19 = #M_RST * 20 = #MONARCH * 21 = #LED_ALARM * 22 = #LED_ACT * 23 = #LED_STATUS1 * 24 = #LED_STATUS2 */ mfsdr(SDR0_PFC0, sdrreg); mtsdr(SDR0_PFC0, (sdrreg & ~SDR0_PFC0_TRE_ENABLE) | 0x00003e00); out32(CONFIG_SYS_GPIO_BASE + 0x018, (USR_LED0 | USR_LED1 | USR_LED2 | USR_LED3)); LED0_OFF(); LED1_OFF(); LED2_OFF(); LED3_OFF(); /* Setup the external bus controller/chip selects */ mtebc(PB0AP, 0x04055200); /* 16MB Strata FLASH */ mtebc(PB0CR, 0xff098000); /* BAS=0xff0 16MB R/W 8-bit */ mtebc(PB1AP, 0x04055200); /* 512KB Socketed AMD FLASH */ mtebc(PB1CR, 0xfe018000); /* BAS=0xfe0 1MB R/W 8-bit */ mtebc(PB6AP, 0x05006400); /* 32-64MB AMD MirrorBit FLASH */ mtebc(PB6CR, 0xf00da000); /* BAS=0xf00 64MB R/W i6-bit */ mtebc(PB7AP, 0x05006400); /* 32-64MB AMD MirrorBit FLASH */ mtebc(PB7CR, 0xf40da000); /* BAS=0xf40 64MB R/W 16-bit */ /* * Setup the interrupt controller polarities, triggers, etc. * * Because of the interrupt handling rework to handle 440GX interrupts * with the common code, we needed to change names of the UIC registers. * Here the new relationship: * * U-Boot name 440GX name * ----------------------- * UIC0 UICB0 * UIC1 UIC0 * UIC2 UIC1 * UIC3 UIC2 */ mtdcr(UIC1SR, 0xffffffff); /* clear all */ mtdcr(UIC1ER, 0x00000000); /* disable all */ mtdcr(UIC1CR, 0x00000003); /* SMI & UIC1 crit are critical */ mtdcr(UIC1PR, 0xfffffe00); /* per ref-board manual */ mtdcr(UIC1TR, 0x01c00000); /* per ref-board manual */ mtdcr(UIC1VR, 0x00000001); /* int31 highest, base=0x000 */ mtdcr(UIC1SR, 0xffffffff); /* clear all */ mtdcr(UIC2SR, 0xffffffff); /* clear all */ mtdcr(UIC2ER, 0x00000000); /* disable all */ mtdcr(UIC2CR, 0x00000000); /* all non-critical */ mtdcr(UIC2PR, 0xffffc0ff); /* per ref-board manual */ mtdcr(UIC2TR, 0x00ff8000); /* per ref-board manual */ mtdcr(UIC2VR, 0x00000001); /* int31 highest, base=0x000 */ mtdcr(UIC2SR, 0xffffffff); /* clear all */ mtdcr(UIC3SR, 0xffffffff); /* clear all */ mtdcr(UIC3ER, 0x00000000); /* disable all */ mtdcr(UIC3CR, 0x00000000); /* all non-critical */ mtdcr(UIC3PR, 0xffffffff); /* per ref-board manual */ mtdcr(UIC3TR, 0x00ff8c0f); /* per ref-board manual */ mtdcr(UIC3VR, 0x00000001); /* int31 highest, base=0x000 */ mtdcr(UIC3SR, 0xffffffff); /* clear all */ mtdcr(UIC0SR, 0xfc000000); /* clear all */ mtdcr(UIC0ER, 0x00000000); /* disable all */ mtdcr(UIC0CR, 0x00000000); /* all non-critical */ mtdcr(UIC0PR, 0xfc000000); /* */ mtdcr(UIC0TR, 0x00000000); /* */ mtdcr(UIC0VR, 0x00000001); /* */ LED0_ON(); return 0; }
/***************************************************************************** * * Cloud_GetCmd * * \param pbuf - string buffer containing data to be sent * bufsize - number of bytes to send * * \return 1 success; 0 failure * * \brief Writes data to Exosite cloud * *****************************************************************************/ int Cloud_GetCmd() { int length; char DataLen[10]; // int http_status = 0; char *cmp_ss = "Content-Length:"; char *cmp = cmp_ss; DWORD serverip = 0; const unsigned char server[6] = SERVERIP ; serverip = (server[3] << 24 & 0xff000000) | (server[2] << 16 & 0xff0000) | (server[1] << 8 & 0xff00) | (server[0] & 0xff); long w, r; char rev[300]; unsigned char len; char *p; unsigned char crlf = 0; int time_out = 0; int tx_buff_size = 250; int tmp_len =0 ; if(status_code == STATUS_INIT||status_code == STATUS_END){ if (sock == INVALID_SOCKET) { sock = TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, HTTP_PORT, TCP_PURPOSE_TCP_CLIENT); // TCP_OPEN_RAM_HOST for using dns name as server name // TCPOpen(serverip, TCP_OPEN_IP_ADDRESS, server_port, TCP_PURPOSE_GENERIC_TCP_CLIENT); if (sock == INVALID_SOCKET) { status_code = STATUS_INIT; // LEDS_OFF(); // LEDS_ON(); return 0; } status_code = STATUS_READY; } else status_code == STATUS_READY; } else if(status_code == STATUS_READY) { if(sent_header) DelayMs(20); w = TCPIsPutReady(sock); if(w<=250ul) { return 0; } if(sent_header){ memset(header, 0, sizeof(header)); length = PostHeaderGenerate("/sendcmd.php", command, 0, 0); remain_count =0 ; sent_header = FALSE; sent_count = 0; } // LED2_ON(); LED1_OFF(); int send_len = strlen(&header[remain_count]); // LED2_ON(); LED1_OFF(); //if(send_len > 254) {LED2_ON(); LED1_OFF()}; /* The max size of sliding window for TCP packet is 254? after testing. * Don't know the reason, but if we set the number of sending data to 250, * the program works fine. * */ tmp_len = send_len>250? 250:send_len; // int tmp_len = IHMS_SocketSend(sock, &header[sent_count], send_len ); tmp_len = TCPPutArray(sock, (BYTE *) &header[remain_count], tmp_len); TCPFlush((TCP_SOCKET)sock); LED2_ON(); LED1_OFF(); if(tmp_len<send_len) { remain_count += tmp_len; return 0; } memset(header, 0, sizeof(header)); sent_count = 0; remain_count = 0; status_code = STATUS_RCV; } else if(status_code == STATUS_RCV) { DelayMs(20); r = TCPIsGetReady((TCP_SOCKET) sock); if(r<200u){ LED2_ON(); return 0;} // now read all data in RX buffer int count = 0; do { r = TCPGetArray((TCP_SOCKET)sock, (BYTE *)&rev[count], 300); count = count + r; rev[count]=0; r = TCPIsGetReady((TCP_SOCKET) sock); }while(r>0u); rev[count] = 0 ; TCPClose((TCP_SOCKET)sock); status_code = STATUS_END; sock = INVALID_SOCKET; status_code = STATUS_END; sent_header = TRUE; //now it's time to read time command = GetServerCmd(rev, "cmd="); cmd_no = GetServerCmd(rev, "no="); return 1; } return 0; }
static inline void LED_SHOW_ACTIVE_BITS(I2C_TypeDef *regs) { uint16_t CR1 = regs->CR1; uint16_t SR1 = regs->SR1; uint16_t SR2 = regs->SR2; // Note: reading SR1 and then SR2 will clear ADDR bits LED1_ON(); // 1 Start if (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_SB, SR1 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); // 2 Addr if (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_ADDR, SR1 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); // 3 BTF if (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_BTF, SR1 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); // 4 ERROR if (( SR1 & I2C_SR1_BITS_ERR ) != 0x0000) LED2_ON(); else LED2_OFF(); LED2_OFF(); // Anything? if (( SR1 + SR2) != 0x0000) LED2_ON(); else LED2_OFF(); LED2_OFF(); LED1_OFF(); LED1_ON(); // 1 Start if (BIT_X_IS_SET_IN_REG( I2C_CR1_BIT_START, CR1 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); // 2 Stop if (BIT_X_IS_SET_IN_REG( I2C_CR1_BIT_STOP, CR1 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); // 3 Busy if (BIT_X_IS_SET_IN_REG( I2C_SR2_BIT_BUSY, SR2 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); // 4 Tra if (BIT_X_IS_SET_IN_REG( I2C_SR2_BIT_TRA, SR2 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); // 5 Master if (BIT_X_IS_SET_IN_REG( I2C_SR2_BIT_MSL, SR2 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); LED1_OFF(); //#define I2C_DEBUG_LED_CONTROL #ifdef I2C_DEBUG_LED_CONTROL LED1_ON(); // 1 Anything CR? if (( CR1) != 0x0000) LED2_ON(); else LED2_OFF(); LED2_OFF(); // 2 PE if (BIT_X_IS_SET_IN_REG( I2C_CR1_BIT_PE, CR1 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); // 3 SWRESET if (BIT_X_IS_SET_IN_REG( I2C_CR1_BIT_SWRST, CR1 ) ) LED2_ON(); else LED2_OFF(); LED2_OFF(); LED1_OFF(); #endif }
void HallPLLCtrl(void) { static uint8_t ii,jj; int32_t LSdata1,LSdata2; LED2Toggle(); Hall_Temp=HALL_DATA(); //if(Hall_TempOld!=Hall_Temp) if(Hall_Temp==HallTemp[Hall_TempOld]) { Hall_TempOld=Hall_Temp; TPWM_Num[Hall_TempOld]=TPWM_Cnt[Hall_TempOld]; TPWM_Cnt[Hall_TempOld]=0; //Speed LSdata1=0; for(jj=0;jj<6;jj++) LSdata1+=TPWM_Num[jj+1]; SpeedCnt=LSdata1/6; //Angle TDelta_angle=65536/TPWM_Num[Hall_TempOld]; if(TCnt_Num>100) //100次霍尔换向允许切换到360度校准一次模式 { if(SpeedData>600) TRun_Flag=1; //600RPM次霍尔换向切换到360度校准一次模式 else TRun_Flag=0; } else TCnt_Num++; if(TRun_Flag) { Delta_angle=TDelta_angle; AngleError=SVM_Angle-Hall_Angle[Hall_TempOld]; //AngleError=_Q15abs(AngleError); if(Hall_TempOld==2) { SVM_Angle=Hall_Angle[Hall_TempOld]; } LED1_ON(); } else { if(PWM_Cnt) Delta_angle=ANGLE_60D/PWM_Cnt; else Delta_angle=1; if(TCnt_Num<10) //方波启动 { SVM_Angle=Hall_Angle[Hall_TempOld]+ANGLE_60D/2; Delta_angle=0; } else //10个霍尔变化之后切入FOC运行 { SVM_Angle=Hall_Angle[Hall_TempOld]; } LED1_OFF(); } PWM_Cnt=0; Limit_angle=0; } else if(Hall_TempOld==HallTemp[Hall_Temp]) { Hall_TempOld=Hall_Temp; TCnt_Num=0; Delta_angle=0; SVM_Angle=Hall_Angle[Hall_TempOld]+ANGLE_60D/2; PWM_Cnt=0xFFFF; } else{} }
/** * The task for generating button events, also does terminal and ping sending */ static void vButtonTask( int8_t *pvParameters ) { uint8_t event; uint8_t buttons = 0; uint8_t s1_count = 0; uint8_t s2_count = 0; int16_t byte; uint8_t i; uint8_t channel; pvParameters; N710_BUTTON_INIT(); vTaskDelay( 200 / portTICK_RATE_MS ); stack_event = stack_service_init(NULL); /* Open socket for stack status message */ channel = mac_current_channel(); while (1) { if(gw_assoc_state == 0 && scan_active == 0) { LED1_OFF(); scan_active=1; scan_start = xTaskGetTickCount(); gw_discover(); } /* Sleep for 10 ms or received from UART */ byte = debug_read_blocking(10 / portTICK_RATE_MS); if (byte != -1) { switch(byte) { case '1': /*send a button 1 event*/ event = 1; xQueueSend( button_events, ( void * ) &event, (portTickType) 0 ); break; case '2': /*send a button 2 event*/ event = 2; xQueueSend( button_events, ( void * ) &event, (portTickType) 0 ); break; case '\r': debug("\r\n"); break; case 'm': { sockaddr_t mac; rf_mac_get(&mac); debug("MAC: "); debug_address(&mac); debug("\r\n"); } break; case 'p': if(ping_active == 0) { echo_result.count=0; if(ping(NULL, &echo_result) == pdTRUE) /* Broadcast */ { ping_start = xTaskGetTickCount(); ping_active = 2; debug("Ping\r\n"); } else debug("No buffer.\r\n"); } break; case 'u': if(ping_active == 0) { echo_result.count=0; if(udp_echo(NULL, &echo_result) == pdTRUE) { ping_start = xTaskGetTickCount(); ping_active = 1; debug("udp echo_req()\r\n"); } else debug("No buffer.\r\n"); } break; /*case 'C': if (channel < 26) channel++; channel++; case 'c': if (channel > 11) channel--; mac_set_channel(channel); debug("Channel: "); debug_int(channel); debug("\r\n"); break;*/ default: debug_put(byte); } } /* Read button (S1 and S2) status */ if (N710_BUTTON_1 == 1) { if (s1_count > 5) { event = 1; if (s1_count >= 100) event |= 0x80; /*long keypress*/ xQueueSend( button_events, ( void * ) &event, (portTickType) 0 ); } s1_count = 0; } else { if (s1_count < 100) { s1_count++; } } if (N710_BUTTON_2 == 1) { if (s2_count > 5) { event = 2; if (s2_count >= 100) event |= 0x80; /*long keypress*/ xQueueSend( button_events, ( void * ) &event, (portTickType) 0 ); } s2_count = 0; } else { if (s2_count < 100) { s2_count++; } } /*LED blinkers*/ if (led1_count) { led1_count--; LED1_ON(); } else { LED1_OFF(); } if (led2_count) { led2_count--; LED2_ON(); } else { LED2_OFF(); } buttons = 0; if (LED1()) { buttons |= 1; } if (LED2()) { buttons |= 2; } ssi_sensor_update(3, (uint32_t) buttons); /* ping response handling */ if ((xTaskGetTickCount() - ping_start)*portTICK_RATE_MS > 1000 && ping_active) { debug("Ping timeout.\r\n"); stop_ping(); if(echo_result.count) { debug("Response: \r\n"); for(i=0; i<echo_result.count; i++) { debug_address(&(echo_result.result[i].src)); debug(" "); debug_int(echo_result.result[i].rssi); debug(" dbm, "); debug_int(echo_result.result[i].time); debug(" ms\r\n"); vTaskDelay(4); } echo_result.count=0; } else { debug("No response.\r\n"); } ping_active = 0; } /* stack events */ if(stack_event) { buffer_t *buffer = waiting_stack_event(10); if(buffer) { switch (parse_event_message(buffer)) { case BROKEN_LINK: buffer->dst_sa.port = datasensor_address.port; if(memcmp(&datasensor_address.address, &(buffer->dst_sa.address), 8) == 0) { gw_assoc_state = 0; datasensor_address.addr_type = ADDR_NONE; LED1_OFF(); } break; case ROUTER_DISCOVER_RESPONSE: scan_active=0; if(gw_assoc_state==0) { memcpy(datasensor_address.address, buffer->src_sa.address, 8); datasensor_address.addr_type = buffer->src_sa.addr_type ; gw_assoc_state=1; LED1_ON(); } break; default: break; } if(buffer) { socket_buffer_free(buffer); buffer = 0; } } } /*end stack events*/ if (scan_active == 1 && (xTaskGetTickCount() - scan_start)*portTICK_RATE_MS > 1000) { mac_gw_discover(); scan_start = xTaskGetTickCount(); } } /*end main loop*/ }
int board_early_init_f(void) { unsigned long sdrreg; /* TBS: Setup the GPIO access for the user LEDs */ mfsdr(sdr_pfc0, sdrreg); mtsdr(sdr_pfc0, (sdrreg & ~0x00000100) | 0x00000E00); out32(CFG_GPIO_BASE + 0x018, (USR_LED0 | USR_LED1 | USR_LED2 | USR_LED3)); LED0_OFF(); LED1_OFF(); LED2_OFF(); LED3_OFF(); /*-------------------------------------------------------------------- * Setup the external bus controller/chip selects *-------------------------------------------------------------------*/ /* set the bus controller */ mtebc (pb0ap, 0x04055200); /* FLASH/SRAM */ mtebc (pb0cr, 0xfff18000); /* BAS=0xfff 1MB R/W 8-bit */ mtebc (pb1ap, 0x04055200); /* FLASH/SRAM */ mtebc (pb1cr, 0xfe098000); /* BAS=0xff8 16MB R/W 8-bit */ /*-------------------------------------------------------------------- * Setup the interrupt controller polarities, triggers, etc. *-------------------------------------------------------------------*/ mtdcr (uic0sr, 0xffffffff); /* clear all */ mtdcr (uic0er, 0x00000000); /* disable all */ mtdcr (uic0cr, 0x00000003); /* SMI & UIC1 crit are critical */ mtdcr (uic0pr, 0xfffffe00); /* per ref-board manual */ mtdcr (uic0tr, 0x01c00000); /* per ref-board manual */ mtdcr (uic0vr, 0x00000001); /* int31 highest, base=0x000 */ mtdcr (uic0sr, 0xffffffff); /* clear all */ mtdcr (uic1sr, 0xffffffff); /* clear all */ mtdcr (uic1er, 0x00000000); /* disable all */ mtdcr (uic1cr, 0x00000000); /* all non-critical */ mtdcr (uic1pr, 0xffffc0ff); /* per ref-board manual */ mtdcr (uic1tr, 0x00ff8000); /* per ref-board manual */ mtdcr (uic1vr, 0x00000001); /* int31 highest, base=0x000 */ mtdcr (uic1sr, 0xffffffff); /* clear all */ mtdcr (uic2sr, 0xffffffff); /* clear all */ mtdcr (uic2er, 0x00000000); /* disable all */ mtdcr (uic2cr, 0x00000000); /* all non-critical */ mtdcr (uic2pr, 0xffffffff); /* per ref-board manual */ mtdcr (uic2tr, 0x00ff8c0f); /* per ref-board manual */ mtdcr (uic2vr, 0x00000001); /* int31 highest, base=0x000 */ mtdcr (uic2sr, 0xffffffff); /* clear all */ mtdcr (uicb0sr, 0xfc000000); /* clear all */ mtdcr (uicb0er, 0x00000000); /* disable all */ mtdcr (uicb0cr, 0x00000000); /* all non-critical */ mtdcr (uicb0pr, 0xfc000000); /* */ mtdcr (uicb0tr, 0x00000000); /* */ mtdcr (uicb0vr, 0x00000001); /* */ LED0_ON(); return 0; }
/** * @brief Main program. * @param None * @retval None */ void main(void) { CLK_Config(); FlashInit(); sim(); // disable interrupts GPIO_Init(GPIOA, GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Fast); GPIO_Init(GPIOB, GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Fast); GPIO_Init(GPIOC, GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Fast); GPIO_Init(GPIOD, GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Fast); GPIO_Init(GPIOE, GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Fast); GPIO_Init(GPIOF, GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Fast); GPIO_Init(GPIOG, GPIO_Pin_All, GPIO_Mode_Out_PP_Low_Fast); delay1s(5); #ifdef DEBUG AppTrace_Init(); printf("\r\nSTM8L152 Start ...\r\n"); #endif LED_Init(); LED1_ON(); scheduler_init(); // Build count init event count_event.eCount_event = COUNT_INIT; app_sched_event_put(&count_event,sizeof(count_event),count_event_handler); // Build key init event key_event.eKey_event = KEY_INIT; app_sched_event_put(&key_event,sizeof(key_event),key_event_handler); // Build the valve standby event valve_event.eValve_event = VALVE_STANDBY_EVENT; app_sched_event_put(&valve_event,sizeof(valve_event),valve_event_handler); // Build the LCD init event lcd_event.eLcd_event = LCD_INIT; app_sched_event_put(&lcd_event,sizeof(lcd_event),lcd_event_handler); // Build the beeper init event beeper_event.eBeeper_event = BEEPER_INIT; app_sched_event_put(&beeper_event,sizeof(beeper_event),beeper_event_handler); // Build the cc1120 Init event cc112x_event.eCC112x_event = CC112X_INIT_EVENT; app_sched_event_put(&cc112x_event,sizeof(cc112x_event),cc112x_event_handler); // Build the IC card Init event ic_card_event.eIC_event = IC_CARD_INIT; app_sched_event_put(&ic_card_event,sizeof(ic_card_event),ic_event_handler); // Build the IC card Init event battery_event.eBattery_event = INT_BATTERY_EVENT; app_sched_event_put(&battery_event,sizeof(battery_event),battery_event_handler); // enable interrupts rim(); LED1_OFF(); // Infinite loop while (1) { app_sched_execute(); app_evt_wait(); } }
/*! * @brief main function */ int main(void) { int32_t currentTemperature = 0; uint32_t updateBoundariesCounter = 0; int32_t tempArray[UPDATE_BOUNDARIES_TIME * 2]; lowPowerAdcBoundaries_t boundaries; /* Init hardware */ BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); /* Init using Led in Demo app */ LED1_INIT(); LED2_INIT(); /* Set to allow entering vlps mode */ SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeVlp); /* Calibrate param Temperature sensor */ ADC16_CalibrateParams(DEMO_ADC16_BASEADDR); /* Initialize Demo ADC */ if (!ADC16_InitHardwareTrigger(DEMO_ADC16_BASEADDR)) { PRINTF("Failed to do the ADC init\r\n"); return -1; } PRINTF("\n\r ADC LOW POWER DEMO\n"); PRINTF("\r The Low Power ADC project is designed to work with the Tower System or in a stand alone setting\n\n"); PRINTF("\r 1. Set your target board in a place where the temperature is constant.\n"); PRINTF("\r 2. Wait until two Led light turns on.\n"); PRINTF("\r 3. Increment or decrement the temperature to see the changes.\n"); PRINTF("\r Wait two led on...\n\r"); /* setup the HW trigger source */ LPTMR_InitTriggerSourceOfAdc(DEMO_LPTMR_BASE); ADC16_EnableDMA(DEMO_ADC16_BASEADDR, false); NVIC_EnableIRQ(DEMO_ADC16_IRQ_ID); /* Warm up microcontroller and allow to set first boundaries */ while (updateBoundariesCounter < (UPDATE_BOUNDARIES_TIME * 2)) { while (!conversionCompleted) { } currentTemperature = GetCurrentTempValue(); tempArray[updateBoundariesCounter] = currentTemperature; updateBoundariesCounter++; conversionCompleted = false; } /* Temp Sensor Calibration */ boundaries = TempSensorCalibration(updateBoundariesCounter, tempArray); updateBoundariesCounter = 0; /* Two LED is turned on indicating calibration is done */ LED1_ON(); LED2_ON(); /* Wait for user input before beginning demo */ PRINTF("\r Enter any character to begin...\n"); GETCHAR(); PRINTF("\r ---> OK! Main process is running...!\n"); while (1) { /* Prevents the use of wrong values */ while (!conversionCompleted) { } /* Get current Temperature Value */ currentTemperature = GetCurrentTempValue(); /* Store temperature values that are going to be use to calculate average temperature */ tempArray[updateBoundariesCounter] = currentTemperature; if (currentTemperature > boundaries.upperBoundary) { LED2_OFF(); LED1_ON(); } else if (currentTemperature < boundaries.lowerBoundary) { LED2_ON(); LED1_OFF(); } else { LED2_ON(); LED1_ON(); } /* Call update function */ if (updateBoundariesCounter >= (UPDATE_BOUNDARIES_TIME)) { boundaries = TempSensorCalibration(updateBoundariesCounter, tempArray); updateBoundariesCounter = 0; } else { updateBoundariesCounter++; } /* Clear conversionCompleted flag */ conversionCompleted = false; /* Enter to Very Low Power Stop Mode */ SMC_SetPowerModeVlps(SMC); } }
/* main routine Program entry point */ int main(void) { Uint8 TxBuf[BCMsgSize]; Uint8 RxBuf[BCMsgSize]; Uint8 Address; // Address of device in bay Uint8 Destination; // Address we will reply to Uint8 Param,Param2; Uint8 Volume = 0; Uint8 TempInt; #ifdef CTRL_LED Uint8 TempInt; Uint8 RceiveAddress; Uint8 i; i = 0; #endif MainInit(); UART_TxStr("\r\nPower up\r\n"); UART_Rx(RxData, 9); // Input register setting command Address = BCAOutput + ReadPosition(); BCMessageInit(Address); // Set up the UART BCMessageReceive(RxBuf); // Kick off receive if(ReadProductID()) // 1:pill 2:beats box 3:rave ChannelNumbers = 1; else ChannelNumbers = 5;//0:5 position headphone // Enter the main loop LED1_ON(); LED2_ON(); LED_GRAPHICAL_ON(); SetLamps(3); for( ; ; ) { // Run forever Timer_Clear(); DelayMS(LoopRate); TempInt++; SettingsControl(); if (BCRXAvail) { // We have a new message //send data #ifdef SecondUART #ifdef DumpComms UART_TxStr("Receive: "); for (TempInt = BCPSOH; TempInt <= BCPChecksum; TempInt++) { UART_TxUint8(RxBuf[TempInt]); UART_TxChar(' '); } UART_TxStr("\r\n"); #endif #endif if ((RxBuf[BCPAddr] & 0b1111) == Address) // Check it is for us { Destination = RxBuf[BCPAddr] >> 4; // Pre-setup assuming we will reply Destination &= 0b1111; Destination |= Address << 4; TxBuf[BCPAddr] = Destination; DelayMS(2); // Allow line turn around delay switch (RxBuf[BCPType]) { case BCTInquire: // Master request of slave ID TxBuf[BCPType] = BCTInquireAnswer; TxBuf[BCPParam1] = ReadProductID(); TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply break; case BCTLamps: // Set lamps TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf, true); // Send the reply Param = RxBuf[BCPParam1]; SetLamps(Param); break; case BCTVolume: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Volume = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request Volume_Set(Volume,Param2); break; case BCTHeadphoneChGain: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request SetChannelAdjust(Param,Param2); break; case BCTHeadphoneChMax: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request SetChMaxVolume(Param, Param2); break; case BCTAudioFormat: // Audio format set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request WM8960_SetAudioFormat(Param); break; case BCTBrightness: // Set lamp brightness TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf, true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request if (Param == 1) LED1 = Param2; else if(Param == 2) LED2 = Param2; break; case BCTReset: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request BCMessageReceive(RxBuf); // Kick off receive of next frame asm("jmp 0x0000");//reset break; default: // Unknown command TxBuf[BCPType] = BCTNAck; TxBuf[BCPParam1] = BCNUnkownType; TxBuf[BCPParam2] = RxBuf[BCPType]; BCMessageSend(TxBuf,true); // Send the reply // BCMessageReceive(RxBuf); // Kick off receive of next frame break; } //this send command tv change to 031-517-209 board #if VideoTrackCtrl Uint8 VideoTrack; Uint8 SendVideoFlag; if(Volume > 47) { if(SendVideoFlag) { SendVideoFlag = false; if(Address == BCARightBay) { VideoTrack = 1; } else if(Address == BCALeftBay) { VideoTrack = 2; } TxBuf[BCPAddr] = Address << 4; TxBuf[BCPAddr] |= BDCLCD; TxBuf[BCPType] = BCTPlayTrack; TxBuf[BCPParam1] = VideoTrack; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf, true); // Send the reply } } else { SendVideoFlag = 1; } #endif } //this for ctrl LED it itself #ifdef CTRL_LED if(RxBuf[BCPType] == BCTVolume) { RceiveAddress = RxBuf[BCPAddr] & 0b1111; a_Volume[RceiveAddress-BCAOutput] = RxBuf[BCPParam1]; if((a_Volume[RceiveAddress-BCAOutput] > 47) && (LastVolume[RceiveAddress-BCAOutput] > 47))//have volume { if((RceiveAddress) == Address) { LED1_ON(); } else { LED1_OFF(); } } i = 0; for(TempInt = 0; TempInt < 4; ) //all volume off { if((a_Volume[TempInt] <= 47) && (LastVolume[TempInt] <= 47)) i++; TempInt++; } if(i >= TempInt) { LED1_ON(); } LastVolume[RceiveAddress-BCAOutput] = a_Volume[RceiveAddress-BCAOutput]; } #endif BCMessageReceive(RxBuf); // Kick off receive of next frame } }
int main(void) { #ifndef HOST_VERSION /* brake */ BRAKE_DDR(); BRAKE_OFF(); /* CPLD reset on PG3 */ DDRG |= 1<<3; PORTG &= ~(1<<3); /* implicit */ /* LEDS */ DDRJ |= 0x0c; DDRL = 0xc0; LED1_OFF(); LED2_OFF(); LED3_OFF(); LED4_OFF(); #endif memset(&gen, 0, sizeof(gen)); memset(&mainboard, 0, sizeof(mainboard)); mainboard.flags = DO_ENCODERS | DO_CS | DO_RS | DO_POS | DO_POWER | DO_BD | DO_ERRBLOCKING; ballboard.lcob = I2C_COB_NONE; ballboard.rcob = I2C_COB_NONE; /* UART */ uart_init(); uart_register_rx_event(CMDLINE_UART, emergency); #ifndef HOST_VERSION #if CMDLINE_UART == 3 fdevopen(uart3_dev_send, uart3_dev_recv); #elif CMDLINE_UART == 1 fdevopen(uart1_dev_send, uart1_dev_recv); #endif /* check eeprom to avoid to run the bad program */ if (eeprom_read_byte(EEPROM_MAGIC_ADDRESS) != EEPROM_MAGIC_MAINBOARD) { int c; sei(); printf_P(PSTR("Bad eeprom value ('f' to force)\r\n")); c = uart_recv(CMDLINE_UART); if (c == 'f') eeprom_write_byte(EEPROM_MAGIC_ADDRESS, EEPROM_MAGIC_MAINBOARD); wait_ms(100); bootloader(); } #endif /* ! HOST_VERSION */ /* LOGS */ error_register_emerg(mylog); error_register_error(mylog); error_register_warning(mylog); error_register_notice(mylog); error_register_debug(mylog); #ifndef HOST_VERSION /* SPI + ENCODERS */ encoders_spi_init(); /* this will also init spi hardware */ /* I2C */ i2c_init(I2C_MODE_MASTER, I2C_MAINBOARD_ADDR); i2c_protocol_init(); i2c_register_recv_event(i2c_recvevent); i2c_register_send_event(i2c_sendevent); /* TIMER */ timer_init(); timer0_register_OV_intr(main_timer_interrupt); /* PWM */ PWM_NG_TIMER_16BITS_INIT(1, TIMER_16_MODE_PWM_10, TIMER1_PRESCALER_DIV_1); PWM_NG_TIMER_16BITS_INIT(4, TIMER_16_MODE_PWM_10, TIMER4_PRESCALER_DIV_1); PWM_NG_INIT16(&gen.pwm1_4A, 4, A, 10, PWM_NG_MODE_SIGNED, &PORTD, 4); PWM_NG_INIT16(&gen.pwm2_4B, 4, B, 10, PWM_NG_MODE_SIGNED | PWM_NG_MODE_SIGN_INVERTED, &PORTD, 5); PWM_NG_INIT16(&gen.pwm3_1A, 1, A, 10, PWM_NG_MODE_SIGNED, &PORTD, 6); PWM_NG_INIT16(&gen.pwm4_1B, 1, B, 10, PWM_NG_MODE_SIGNED, &PORTD, 7); /* servos */ PWM_NG_TIMER_16BITS_INIT(3, TIMER_16_MODE_PWM_10, TIMER1_PRESCALER_DIV_256); PWM_NG_INIT16(&gen.servo1, 3, C, 10, PWM_NG_MODE_NORMAL, NULL, 0); PWM_NG_TIMER_16BITS_INIT(5, TIMER_16_MODE_PWM_10, TIMER1_PRESCALER_DIV_256); PWM_NG_INIT16(&gen.servo2, 5, A, 10, PWM_NG_MODE_NORMAL, NULL, 0); PWM_NG_INIT16(&gen.servo3, 5, B, 10, PWM_NG_MODE_NORMAL, NULL, 0); PWM_NG_INIT16(&gen.servo4, 5, C, 10, PWM_NG_MODE_NORMAL, NULL, 0); support_balls_deploy(); /* init pwm for servos */ #endif /* !HOST_VERSION */ /* SCHEDULER */ scheduler_init(); #ifdef HOST_VERSION hostsim_init(); robotsim_init(); #endif #ifndef HOST_VERSION scheduler_add_periodical_event_priority(do_led_blink, NULL, 100000L / SCHEDULER_UNIT, LED_PRIO); #endif /* !HOST_VERSION */ /* all cs management */ microb_cs_init(); /* TIME */ time_init(TIME_PRIO); /* sensors, will also init hardware adc */ sensor_init(); #ifndef HOST_VERSION /* start i2c slave polling */ scheduler_add_periodical_event_priority(i2c_poll_slaves, NULL, 8000L / SCHEDULER_UNIT, I2C_POLL_PRIO); #endif /* !HOST_VERSION */ /* strat */ gen.logs[0] = E_USER_STRAT; gen.log_level = 5; /* strat-related event */ scheduler_add_periodical_event_priority(strat_event, NULL, 25000L / SCHEDULER_UNIT, STRAT_PRIO); #ifndef HOST_VERSION /* eeprom time monitor */ scheduler_add_periodical_event_priority(do_time_monitor, NULL, 1000000L / SCHEDULER_UNIT, EEPROM_TIME_PRIO); #endif /* !HOST_VERSION */ sei(); strat_db_init(); printf_P(PSTR("\r\n")); printf_P(PSTR("Respect et robustesse.\r\n")); #ifndef HOST_VERSION { uint16_t seconds; seconds = eeprom_read_word(EEPROM_TIME_ADDRESS); printf_P(PSTR("Running since %d mn %d\r\n"), seconds/60, seconds%60); } #endif #ifdef HOST_VERSION strat_reset_pos(400, COLOR_Y(400), COLOR_A(-90)); #endif cmdline_interact(); return 0; }
void led1_off() { LED1_ENABLE(); LED1_OFF(); }
static inline void i2c_irq(struct i2c_periph *periph) { /* There are 7 possible event reasons to get here + all errors If IT_EV_FEN ------------------------- We are always interested in all IT_EV_FEV: all are required. 1) SB // Start Condition Success in Master mode 2) ADDR // Address sent received Acknoledge [ADDR10] // -- 10bit address stuff: not used [STOPF] // -- only for slaves: master has no stop interrupt: not used 3) BTF // I2C has stopped working (it is waiting for new data, all buffers are tx_empty/rx_full) // Beware: using the buffered I2C has some interesting properties: - in master receive mode: BTF only occurs after the 2nd received byte: after the first byte is received it is in RD but the I2C can still receive a second byte. Only when the 2nd byte is received while the RxNE is 1 then a BTF occurs (I2C can not continue receiving bytes or they will get lost). During BTF I2C is halted (SCL held low) - in master transmit mode: when writing a byte to WD, you instantly get a new TxE interrupt while the first is not transmitted yet. The byte was pushed to the I2C shift register and the buffer is ready for more. You can already fill new data in the buffer while the first is still being transmitted for max performance transmission. // Beware: besides data buffering you can/must plan several consecutive actions. You can send 2 bytes to the buffer, ask for a stop and a new start in one go. - thanks to / because of this buffering and event sheduling there is not 1 interrupt per start / byte / stop This also means you must think more in advance and a transaction could be popped from the transaction stack even before it's stop condition is actually generated. // Beware: the order in which Status (and other register) is read determines how flags are cleared. You should NOT simply read SR1 & SR2 every time If IT_EV_FEN AND IT_EV_BUF -------------------------- Buffer event are not always wanted and are typically switched on during longer data transfers. Make sure to turn off in time. 4) RxNE 5) TxE -------------------------------------------------------------------------------------------------- The STM waits indefinately (holding SCL low) for user interaction: a) after a master-start (waiting for address) b) after an address (waiting for data) not during data sending when using buffered c) after the last byte is transmitted (waiting for either stop or restart) not during data receiving when using buffered not after the last byte is received - The STM I2C stalls indefinately when a stop condition was attempted that did not succeed. The BUSY flag remains on. - There is no STOP interrupt. Caution Reading the status: - Caution: this clears several flags and can start transmissions etc... - Certain flags like STOP / (N)ACK need to be guaranteed to be set before the transmission of the byte is finished. At higher clock rates that can be quite fast: so we allow no other interrupt to be triggered in between reading the status and setting all needed flags */ // Here we go ... // Apparently we got an I2C interrupt: EVT BUF or ERR #ifdef I2C_DEBUG_LED // Notify ISR is triggered LED1_ON(); LED1_OFF(); #endif // Save Some Direct Access to the I2C Registers ... uint32_t i2c = (uint32_t) periph->reg_addr; ///////////////////////////// // Check if we were ready ... if (periph->trans_extract_idx == periph->trans_insert_idx) { // Nothing Left To Do #ifdef I2C_DEBUG_LED LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); // no transaction and also an error? LED_SHOW_ACTIVE_BITS(regs); #endif // If we still get an interrupt but there are no more things to do // (which can happen if an event was sheduled just before a bus error occurs) // (or can happen if both error and event interrupts were called together [the 2nd will then get this error]) // since there is nothing more to do: its easy: just stop: clear all interrupt generating bits // Count The Errors i2c_error(periph); // Clear Running Events stmi2c_clear_pending_interrupts(i2c); // Mark this as a special error periph->errors->last_unexpected_event++; // Document the current Status periph->status = I2CIdle; // There are no transactions anymore: return // further-on in this routine we need a transaction pointer: so we are not allowed to continue return; } // get the I2C transaction we were working on ... enum STMI2CSubTransactionStatus ret = 0; struct i2c_transaction* trans = periph->trans[periph->trans_extract_idx]; /////////////////////////// // If there was an error: if (( I2C_SR1(i2c) & I2C_SR1_ERR_MASK ) != 0x0000) { #ifdef I2C_DEBUG_LED LED1_ON(); LED2_ON(); LED1_OFF(); LED2_OFF(); LED_SHOW_ACTIVE_BITS(regs); #endif // Notify everyone about the error ... // Set result in transaction trans->status = I2CTransFailed; // Document the current Status periph->status = I2CFailed; // Make sure a TxRx does not Restart trans->type = I2CTransRx; // Count The Errors i2c_error(periph); // Clear Running Events stmi2c_clear_pending_interrupts(i2c); // Now continue as if everything was normal from now on ret = STMI2C_SubTra_Ready; } /////////////////////////// // Normal Event: else { /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// // // SUB-TRANSACTION HANDLER if (trans->type == I2CTransRx) // TxRx are converted to Rx after the Tx Part { switch (trans->len_r) { case 1: ret = stmi2c_read1(i2c,periph,trans); break; case 2: ret = stmi2c_read2(i2c,periph,trans); break; default: ret = stmi2c_readmany(i2c,periph,trans); break; } } else // TxRx or Tx { ret = stmi2c_send(i2c,periph,trans); } } ///////////////////////////////// // Sub-transaction has finished if (ret != STMI2C_SubTra_Busy) { // Ready or SubTraError // -ready: with or without stop already asked // In case of unexpected event condition during subtransaction handling: if (ret == STMI2C_SubTra_Error) { // Tell everyone about the subtransaction error: // this is the previously called SPURRIOUS INTERRUPT periph->status = I2CFailed; trans->type = I2CTransRx; // Avoid possible restart trans->status = I2CTransFailed; // Notify Ready periph->errors->unexpected_event_cnt++; // Error #ifdef I2C_DEBUG_LED LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); LED_SHOW_ACTIVE_BITS(regs); #endif // Clear Running Events stmi2c_clear_pending_interrupts(i2c); } // RxTx -> Restart and do Rx part if (trans->type == I2CTransTxRx) { trans->type = I2CTransRx; periph->status = I2CStartRequested; i2c_send_start(i2c); // Silent any BTF that would occur before SB i2c_send_data(i2c, 0x00); } // If a restart is not needed: Rx part or Tx-only else { // Ready, no stop condition set yet if (ret == STMI2C_SubTra_Ready) { // Program a stop PPRZ_I2C_SEND_STOP(i2c); // Silent any BTF that would occur before STOP is executed i2c_send_data(i2c, 0x00); } // Jump to the next transaction periph->trans_extract_idx++; if (periph->trans_extract_idx >= I2C_TRANSACTION_QUEUE_LEN) periph->trans_extract_idx = 0; // Tell everyone we are ready periph->status = I2CIdle; // if we have no more transaction to process, stop here if (periph->trans_extract_idx == periph->trans_insert_idx) { periph->watchdog = -1; // stop watchdog #ifdef I2C_DEBUG_LED LED2_ON(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED2_OFF(); #endif } // if not, start next transaction else { // Restart transaction doing the Rx part now // --- moved to idle function PPRZ_I2C_SEND_START(periph); // ------ } } } return; }
void i2c_setbitrate(struct i2c_periph *periph, int bitrate) { // If NOT Busy if (i2c_idle(periph)) { volatile int devider; volatile int risetime; uint32_t i2c = (uint32_t) periph->reg_addr; /***************************************************** Bitrate: -CR2 + CCR + TRISE registers -only change when PE=0 e.g. 10kHz: 36MHz + Standard 0x708 + 0x25 70kHz: 36MHz + Standard 0x101 + 400kHz: 36MHz + Fast 0x1E + 0xb // 1) Program peripheral input clock CR2: to get correct timings // 2) Configure clock control registers // 3) Configure rise time register ******************************************************/ if (bitrate < 3000) bitrate = 3000; // 36MHz, fast scl: 2counts low 1 count high -> / 3: devider = 18000 / (bitrate/1000); // never allow faster than 600kbps if (devider < 20) devider = 20; // no overflow either if (devider >=4095) devider = 4095; // risetime can be up to 1/6th of the period risetime = 1000000 / (bitrate/1000) / 6 / 28; if (risetime < 10) risetime = 10; // more will overflow the register: for more you should lower the FREQ if (risetime >=31) risetime = 31; // we do not expect an interrupt as the interface should have been idle, but just in case... __disable_irq(); // this code is in user space: // CCR can only be written when PE is disabled // p731 note 5 I2C_CR1(i2c) &= ~ I2C_CR1_PE; // 1) I2C_CR2(i2c) = 0x0324; // 2) //I2C_CCR(i2c) = 0x8000 + devider; I2C_CCR(i2c) = 0x0000 + devider; // 3) I2C_TRISE(i2c) = risetime; // Re-Enable I2C_CR1(i2c) |= I2C_CR1_PE; __enable_irq(); #ifdef I2C_DEBUG_LED __disable_irq(); // this code is in user space: LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); __enable_irq(); #endif } }
static inline void i2c_irq(struct i2c_periph *periph) { /* There are 7 possible reasons to get here: If IT_EV_FEN ------------------------- We are always interested in all IT_EV_FEV: all are required. 1) SB // Start Condition Success in Master mode 2) ADDR // Address sent received Acknoledge [3 ADDR10] // -- 10bit address stuff [4 STOPF] // -- only for slaves: master has no stop interrupt 5) BTF // I2C has stopped working (it is waiting for new data, all buffers are tx_empty/rx_full) // Beware: using the buffered I2C has some interesting properties: -in master receive mode: BTF only occurs after the 2nd received byte: after the first byte is received it is in RD but the I2C can still receive a second byte. Only when the 2nd byte is received while the RxNE is 1 then a BTF occurs (I2C can not continue receiving bytes or they will get lost). During BTF I2C is halted (SCL held low) -in master transmitmode: when writing a byte to WD, you instantly get a new TxE interrupt while the first is not transmitted yet. The byte was pushed to the I2C shift register and the buffer is ready for more. You can already fill new data in the buffer while the first is still being transmitted for max performance transmission. // Beware: besides data buffering you can/must plan several consecutive actions. You can send 2 bytes to the buffer, ask for a stop and a new start in one go. -thanks to / because of this buffering and event sheduling there is not 1 interrupt per start / byte / stop This also means you must think more in advance and a transaction could be popped from the stack even before it is actually completely transmitted. But then you would not know the result yet so you have to keep it until the result is known. // Beware: the order in which Status is read determines how flags are cleared. You should not just read SR1 & SR2 every time If IT_EV_FEN AND IT_EV_BUF -------------------------- Buffer event are not always wanted and are tipically switched on during longer data transfers. Make sure to turn off in time. 6) RxNE 7) TxE -------------------------------------------------------------------------------------------------- // This driver uses only a subset of the pprz_i2c_states for several reasons: // -we have less interrupts than the I2CStatus states (for efficiency) // -STM32 has such a powerfull I2C engine with plenty of status register flags that only little extra status information needs to be stored. // Status is re-used (abused) to remember the last COMMAND THAT WAS SENT to the STM I2C hardware. // TODO: check which are used enum I2CStatus { I2CIdle, // No more last command I2CStartRequested, // Last command was start I2CRestartRequested, // Last command was restart I2CStopRequested, // Very important to not send double stop conditions I2CSendingByte, // Some address/data operation // Following are not used I2CReadingByte, I2CAddrWrSent, I2CAddrRdSent, I2CSendingLastByte, I2CReadingLastByte, I2CComplete, I2CFailed }; --------- The STM waits indefinately (holding SCL low) for user interaction: a) after a master-start (waiting for address) b) after an address (waiting for data) not during data sending when using buffered c) after the last byte is transmitted (waiting for either stop or restart) not during data receiving when using buffered not after the last byte is received -The STM I2C stalls indefinately when a stop condition was attempted that did not succeed. The BUSY flag remains on. -There is no STOP interrupt: use needs another way to finish. */ /////////////////////////////////////////////////////////////////////////////////// // Reading the status: // - Caution: this clears several flags and can start transmissions etc... // - Certain flags like STOP / (N)ACK need to be guaranteed to be set before // the transmission of the byte is finished. At higher clock rates that can be // quite fast: so we allow no other interrupt to be triggered in between // reading the status and setting all needed flags // Direct Access to the I2C Registers // Do not read SR2 as it might start the reading while an (n)ack bit might be needed first I2C_TypeDef *regs = (I2C_TypeDef *) periph->reg_addr; #ifdef I2C_DEBUG_LED LED1_ON(); LED1_OFF(); #endif /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// // // TRANSACTION HANDLER enum STMI2CSubTransactionStatus ret = 0; /////////////////////// // Nothing Left To Do if (periph->trans_extract_idx == periph->trans_insert_idx) { #ifdef I2C_DEBUG_LED LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); // no transaction and also an error? LED_SHOW_ACTIVE_BITS(regs); #endif // If we still get an interrupt but there are no more things to do // (which can happen if an event was sheduled just before a bus error occurs) // then its easy: just stop: clear all interrupt generating bits // Clear Running Events stmi2c_clear_pending_interrupts(regs); // Count The Errors i2c_error(periph); // Mark this as a special error periph->errors->unexpected_event_cnt++; periph->status = I2CIdle; // There are no transactions anymore: // furtheron we need a transaction pointer: so we are not allowed to continue return; } struct i2c_transaction* trans = periph->trans[periph->trans_extract_idx]; /////////////////////////// // If there was an error: if (( regs->SR1 & I2C_SR1_BITS_ERR ) != 0x0000) { #ifdef I2C_DEBUG_LED LED1_ON(); LED2_ON(); LED1_OFF(); LED2_OFF(); LED_SHOW_ACTIVE_BITS(regs); #endif // Set result in transaction trans->status = I2CTransFailed; // Prepare for next ret = STMI2C_SubTra_Ready; // Make sure a TxRx does not Restart trans->type = I2CTransRx; // Clear Running Events stmi2c_clear_pending_interrupts(regs); // Count The Errors i2c_error(periph); } /////////////////////////// // Normal Event: else { if (trans->type == I2CTransRx) // TxRx are converted to Rx after the Tx Part { switch (trans->len_r) { case 1: ret = stmi2c_read1(regs,trans); break; case 2: ret = stmi2c_read2(regs,trans); break; default: ret = stmi2c_readmany(regs,periph, trans); break; } } else // TxRx or Tx { ret = stmi2c_send(regs,periph,trans); } } ///////////////////////////////// // Sub-transaction has finished if (ret != STMI2C_SubTra_Busy) { // If a restart is not needed if (trans->type != I2CTransTxRx) { // Ready, no stop condition set yet if (ret == STMI2C_SubTra_Ready) { // Program a stop PPRZ_I2C_SEND_STOP(regs); // Silent any BTF that would occur before STOP is executed regs->DR = 0x00; } // Jump to the next transaction periph->trans_extract_idx++; if (periph->trans_extract_idx >= I2C_TRANSACTION_QUEUE_LEN) periph->trans_extract_idx = 0; // Tell everyone we are ready periph->status = I2CIdle; // if we have no more transaction to process, stop here if (periph->trans_extract_idx == periph->trans_insert_idx) { #ifdef I2C_DEBUG_LED LED2_ON(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED2_OFF(); #endif } // if not, start next transaction else { // Restart transaction doing the Rx part now // --- moved to idle function PPRZ_I2C_SEND_START(periph); // ------ } } // RxTx -> Restart and do Rx part else { trans->type = I2CTransRx; periph->status = I2CStartRequested; regs->CR1 |= I2C_CR1_BIT_START; // Silent any BTF that would occur before SB regs->DR = 0x00; } } return; }
/// @todo Watchdog timer void i2c_event(void) { #ifdef USE_I2C1 i2c1_watchdog_counter++; #endif #ifdef USE_I2C2 i2c2_watchdog_counter++; if (i2c2_watchdog_counter > 10000) { i2c2.errors->timeout_tlow_cnt++; i2c2_watchdog_counter = 0; } #ifdef I2C_DEBUG_LED if (i2c2_watchdog_counter == 0) { __disable_irq(); LED2_ON(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); if (i2c2.status == I2CIdle) { LED1_ON(); LED1_OFF(); } else if (i2c2.status == I2CStartRequested) { LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); } LED2_OFF(); //regs = (I2C_TypeDef *) i2c2.reg_addr; //LED_SHOW_ACTIVE_BITS(regs); __enable_irq(); } #endif //if (i2c2.status == I2CIdle) { //if (i2c_idle(&i2c2)) { //__disable_irq(); // More work to do //if (i2c2.trans_extract_idx != i2c2.trans_insert_idx) { // Restart transaction doing the Rx part now //PPRZ_I2C_SEND_START(&i2c2); } //__enable_irq(); } } #endif #ifdef USE_I2C3 i2c3_watchdog_counter++; #endif }
void i2c_event(void) { static uint32_t cnt = 0; //I2C_TypeDef *regs; cnt++; if (cnt > 10000) cnt = 0; #ifndef I2C_DEBUG_LED #ifdef USE_I2C1 if (i2c1.status == I2CIdle) { if (i2c_idle(&i2c1)) { __disable_irq(); // More work to do if (i2c1.trans_extract_idx != i2c1.trans_insert_idx) { // Restart transaction doing the Rx part now PPRZ_I2C_SEND_START(&i2c1); } __enable_irq(); } } #endif #endif #ifdef USE_I2C2 #ifdef I2C_DEBUG_LED if (cnt == 0) { __disable_irq(); LED2_ON(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); if (i2c2.status == I2CIdle) { LED1_ON(); LED1_OFF(); } else if (i2c2.status == I2CStartRequested) { LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); } LED2_OFF(); //regs = (I2C_TypeDef *) i2c2.reg_addr; //LED_SHOW_ACTIVE_BITS(regs); __enable_irq(); } #endif //if (i2c2.status == I2CIdle) { //if (i2c_idle(&i2c2)) { //__disable_irq(); // More work to do //if (i2c2.trans_extract_idx != i2c2.trans_insert_idx) { // Restart transaction doing the Rx part now //PPRZ_I2C_SEND_START(&i2c2); } //__enable_irq(); } } #endif }
/*! * Init board. */ void BoardInit(void) { SPI_InitTypeDef SPI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; #ifdef STM32F10X_MD RCC_APB2PeriphClockCmd( 0 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE); #else #ifdef STM32L1XX_MD RCC_AHBPeriphClockCmd( 0 | RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB , ENABLE); #else #error "Unknown CPU type" #endif #endif DBGMCU_Config( 0 | DBGMCU_TIM2_STOP | DBGMCU_TIM3_STOP | DBGMCU_SLEEP | DBGMCU_STOP | DBGMCU_STANDBY , ENABLE); MAC_TIMER_CLOCK(); DELAY_TIMER_CLOCK(); LED1_OFF(); LED1_INIT(); LED2_OFF(); LED2_INIT(); TimerInit( MAC_TIMER, MAC_TIMER_PRESCALER, MAC_TIMER_IRQn ); TimerInit( DELAY_TIMER, DELAY_TIMER_PRESCALER, 0 ); RF_SDN_HIGH(); RF_SDN_INIT(); RF_NSS_HIGH(); RF_NSS_INIT(); RF_SCLK_INIT(); RF_MISO_INIT(); RF_MOSI_INIT(); RF_IRQ_INIT(); DELAY_uS(10 * DELAY_1MS_TIMER2); RF_SDN_LOW(); DELAY_uS(50 * DELAY_1MS_TIMER2); RF_SPI_CLOCK(); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(RF_SPI, &SPI_InitStructure); SPI_Cmd(RF_SPI, ENABLE); #ifdef STM32F10X_MD GPIO_EXTILineConfig(RF_IRQ_EXT_PORT, RF_IRQ_EXT_PIN); #else #ifdef STM32L1XX_MD SYSCFG_EXTILineConfig(RF_IRQ_EXT_PORT, RF_IRQ_EXT_PIN); #endif #endif EXTI_InitStructure.EXTI_Line = RF_IRQ_EXT_LINE; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); DISABLE_MAC_EXT_INTERRUPT(); CLEAR_MAC_EXT_INTERRUPT(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = RF_IRQ_EXT_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #ifdef RTC_ENABLED RTC_INIT(); #endif #ifdef UART0_ENABLED Uart0Init(); #endif }
static inline enum STMI2CSubTransactionStatus stmi2c_readmany(I2C_TypeDef *regs, struct i2c_periph *periph, struct i2c_transaction *trans) { uint16_t SR1 = regs->SR1; // Start Condition Was Just Generated if (BIT_X_IS_SET_IN_REG( I2C_SR1_BIT_SB, SR1 ) ) { regs->CR2 &= ~ I2C_CR2_BIT_ITBUFEN; // The first data byte will be acked in read many so the slave knows it should send more regs->CR1 &= ~ I2C_CR1_BIT_POS; regs->CR1 |= I2C_CR1_BIT_ACK; // Clear the SB flag regs->DR = trans->slave_addr | 0x01; } // Address Was Sent else if (BIT_X_IS_SET_IN_REG(I2C_SR1_BIT_ADDR, SR1) ) { periph->idx_buf = 0; // Enable RXNE: receive an interrupt any time a byte is available // only enable if MORE than 3 bytes need to be read if (periph->idx_buf < (trans->len_r - 3)) { regs->CR2 |= I2C_CR2_BIT_ITBUFEN; } // ACK is still on to get more DATA // Read SR2 to clear the ADDR (next byte will start arriving) uint16_t SR2 __attribute__ ((unused)) = regs->SR2; } // one or more bytes are available AND we were interested in Buffer interrupts else if ( (BIT_X_IS_SET_IN_REG(I2C_SR1_BIT_RXNE, SR1) ) && (BIT_X_IS_SET_IN_REG(I2C_CR2_BIT_ITBUFEN, regs->CR2)) ) { // read byte until 3 bytes remain to be read (e.g. len_r = 6, -> idx=3 means idx 3,4,5 = 3 remain to be read if (periph->idx_buf < (trans->len_r - 3)) { trans->buf[periph->idx_buf] = regs->DR; periph->idx_buf ++; } // from : 3bytes -> last byte: do nothing // // finally: this was the last byte else if (periph->idx_buf >= (trans->len_r - 1)) { regs->CR2 &= ~ I2C_CR2_BIT_ITBUFEN; // Last Value trans->buf[periph->idx_buf] = regs->DR; periph->idx_buf ++; // We got all the results trans->status = I2CTransSuccess; return STMI2C_SubTra_Ready_StopRequested; } // Check for end of transaction: start waiting for BTF instead of RXNE if (periph->idx_buf < (trans->len_r - 3)) { regs->CR2 |= I2C_CR2_BIT_ITBUFEN; } else // idx >= len-3: there are 3 bytes to be read { // We want to halt I2C to have sufficient time to clear ACK, so: // Stop listening to RXNE as it will be triggered infinitely since we did not empty the buffer // on the next (second in buffer) received byte BTF will be set (buffer full and I2C halted) regs->CR2 &= ~ I2C_CR2_BIT_ITBUFEN; } } // Buffer is full while this was not a RXNE interrupt else if (BIT_X_IS_SET_IN_REG(I2C_SR1_BIT_BTF, SR1) ) { // Now the shift register and data register contain data(n-2) and data(n-1) // And I2C is halted so we have time // --- Make absolutely sure the next 2 I2C actions are performed with no delay __I2C_REG_CRITICAL_ZONE_START; // First we clear the ACK while the SCL is held low by BTF regs->CR1 &= ~ I2C_CR1_BIT_ACK; // Now that ACK is cleared we read one byte: instantly the last byte is being clocked in... trans->buf[periph->idx_buf] = regs->DR; periph->idx_buf ++; // Now the last byte is being clocked. Stop in MUST be set BEFORE the transfer of the last byte is complete PPRZ_I2C_SEND_STOP(regs); __I2C_REG_CRITICAL_ZONE_STOP; // --- end of critical zone ----------- // read the byte2 we had in the buffer (BTF means 2 bytes available) trans->buf[periph->idx_buf] = regs->DR; periph->idx_buf ++; // Ask for an interrupt to read the last byte (which is normally still busy now) // The last byte will be received with RXNE regs->CR2 |= I2C_CR2_BIT_ITBUFEN; } else // Hardware error { // Error #ifdef I2C_DEBUG_LED LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); #endif return STMI2C_SubTra_Error; } return STMI2C_SubTra_Busy; }
static void vbeacon_rfd( void *pvParameters ) { buffer_t *buffer=0; uint8_t send=0, *ptr, i, sqn=0; int16_t byte; uint16_t count = 0; pause(200); debug_init(115200); pause(300); stack_event = open_stack_event_bus(); /* Open socket for stack status message */ stack_service_init( stack_event,NULL, 0 , NULL ); if(stack_start(NULL)==START_SUCCESS) { debug("Start Ok\r\n"); } /*****************************************************************************************************/ /****************************************************************************************************/ for (;;) { byte = debug_read_blocking(10); if(byte != -1) { switch(byte) { case 'm': ptr=mac_get_mac_pib_parameter(MAC_IEEE_ADDRESS); if(ptr) { ptr +=7; debug("Devices mac-address: "); for(i=0; i< 8 ;i++) { if(i) debug(":"); debug_hex(*ptr--); } debug("\r\n"); } break; case 'b': debug_int(uxQueueMessagesWaiting(buffers)); debug(" buffers available.\r\n"); break; case 'c': ptr=mac_get_mac_pib_parameter(MAC_CURRENT_CHANNEL); if(ptr) { debug("Current channel: "); debug_int(*ptr); debug("\r\n"); } break; case '\r': debug("\r\n"); break; default: debug_put(byte); break; } } if(send && data) { buffer_t *buf = socket_buffer_get(data); if (buf) { /* Create data packet */ /*buf->buf[buf->buf_end++] = 'S'; buf->buf[buf->buf_end++] = 'e'; buf->buf[buf->buf_end++] = 'n'; buf->buf[buf->buf_end++] = 's'; buf->buf[buf->buf_end++] = 'o'; buf->buf[buf->buf_end++] = 'r'; buf->buf[buf->buf_end++] = '_'; buf->buf[buf->buf_end++] = mac_long.address[1]; buf->buf[buf->buf_end++] = mac_long.address[0];*/ buf->buf[buf->buf_end++] = sqn; buf->buf[buf->buf_end++] = 0xc2; buf->buf[buf->buf_end++] = 0x00; buf->buf[buf->buf_end++] = 0x08; buf->buf[buf->buf_end++] = 0x00; buf->buf[buf->buf_end++] = 0x08; buf->buf[buf->buf_end++] = 0x00; buf->buf[buf->buf_end++] = 0x10; buf->buf[buf->buf_end++] = 0x23; buf->buf[buf->buf_end++] = 0x16; if (socket_sendto(data, &cord_address, buf) != pdTRUE) { debug("Data send failed.\r\n"); socket_buffer_free(buf); buf=0; } if(sqn==0x0f) sqn=0; else sqn++; send=0; } } if (count++ >= 400) { send=1; count = 0; } if(stack_event) { buffer=0; buffer = waiting_stack_event(10); if(buffer) { switch (parse_event_message(buffer)) { case BROKEN_LINK: debug("Route broken to "); debug("\r\n"); debug_address(&(buffer->dst_sa)); debug("\r\n"); break; case ASSOCIATION_WITH_COORDINATOR: debug("Assoc ok "); if(get_coord_address(&cord_address) == pdTRUE) { data = socket(MODULE_CUDP, 0); /* Socket for response data from port number 61619 */ if (data) { if (socket_bind(data, &cord_address) != pdTRUE) { debug("Bind failed.\r\n"); } } } break; case NOT_ASSOCIATED: debug("Application design error:\r\n"); debug("RFD try send data before association\r\n"); break; case ASSOCIATION_LOST: if(socket_close(data) == pdTRUE) { data=0; scan_network(); } break; case TOO_LONG_PACKET: debug("Payload Too Length, to "); debug("\r\n"); break; default: break; } if(buffer) { socket_buffer_free(buffer); buffer = 0; } } } LED1_ON(); LED1_OFF(); } }