bool SpidevSPI::Open(const char *spidev) { assert(fd_ < 0); int fd = open(spidev, O_RDWR | O_NOCTTY); if (fd == -1) { perror("Unable to open device"); return false; } fd_ = fd; if (ConfigureSPI()) { spidev_ = spidev; return true; } close(fd); fd_ = -1; return false; }
void InitializeA36772(void) { // Initialize the status register and load the inhibit and fault masks _FAULT_REGISTER = 0; _WARNING_REGISTER = 0; _CONTROL_REGISTER = 0; _NOT_LOGGED_REGISTER = 0; global_data_A36772.message1_energy = 0x00; global_data_A36772.message2_blank = 0x00; global_data_A36772.message3_blank = 0x00; global_data_A36772.dose_switch_value = 0; global_data_A36772.trigger_received = 0; global_data_A36772.delay_time = 0; global_data_A36772.waiting_to_transmit = 0; global_data_A36772.run_time_counter = 0; // --------- BEGIN IO PIN CONFIGURATION ------------------ // Initialize Ouput Pin Latches BEFORE setting the pins to Output PIN_CS_DAC = !OLL_PIN_CS_DAC_SELECTED; PIN_CS_ADC = !OLL_PIN_CS_ADC_SELECTED; PIN_CS_FPGA = !OLL_PIN_CS_FPGA_SELECTED; // ---- Configure the dsPIC ADC Module Analog Inputs------------ // ADPCFG = 0xFFFF; // all are digital I/O // Initialize all I/O Registers TRISA = A36772_TRISA_VALUE; TRISB = A36772_TRISB_VALUE; TRISC = A36772_TRISC_VALUE; TRISD = A36772_TRISD_VALUE; TRISF = A36772_TRISF_VALUE; TRISG = A36772_TRISG_VALUE; // // Config SPI1 for Gun Driver ConfigureSPI(ETM_SPI_PORT_1, A36772_SPI1CON_VALUE, 0, A36772_SPI1STAT_VALUE, SPI_CLK_1_MBIT, FCY_CLK); // // Initialize application specific hardware UART1TX_ON_TRIS = 0; UART1TX_ON_IO = 1; // always enable TX1 // Configure UART Interrupts _U1RXIE = 0; _U1RXIP = 5; _U1TXIE = 0; _U1TXIP = 5; // Set up external INT3 */ // This is the trigger interrupt _INT3IF = 0; // Clear Interrupt flag _INT3IE = 1; // Enable INT3 Interrupt _INT3EP = 1; // Interrupt on falling edge _INT3IP = 7; // Set interrupt to highest priority // ---------- Configure Timers ----------------- // // // Initialize TMR1 // PR1 = A36772_PR1_VALUE; // TMR1 = 0; // _T1IF = 0; // _T1IP = 2; // T1CON = A36772_T1CON_VALUE; // Initialize TMR2 PR2 = A36772_PR2_VALUE; TMR2 = 0; _T2IF = 0; // _T2IP = 5; _T2IP = 2; T2CON = A36772_T2CON_VALUE; // Initialize TMR3 PR3 = A36772_PR3_VALUE; TMR3 = 0; _T3IF = 0; // _T3IP = 5; _T3IP = 2; T3CON = A36772_T3CON_VALUE; // // Configure on-board DAC SetupLTC265X(&U32_LTC2654, ETM_SPI_PORT_2, FCY_CLK, LTC265X_SPI_2_5_M_BIT, _PIN_RG15, _PIN_RC1); // // //Configure EEPROM ETMEEPromConfigureExternalDevice(EEPROM_SIZE_8K_BYTES, FCY_CLK, 400000, EEPROM_I2C_ADDRESS_0, 1); // // // ------------- Configure Internal ADC --------- // // ADCON1 = ADCON1_SETTING; // Configure the high speed ADC module based on H file parameters // ADCON2 = ADCON2_SETTING; // Configure the high speed ADC module based on H file parameters // ADCON3 = ADCON3_SETTING; // Configure the high speed ADC module based on H file parameters // ADCHS = ADCHS_SETTING; // Configure the high speed ADC module based on H file parameters // // ADPCFG = ADPCFG_SETTING; // Set which pins are analog and which are digital I/O // ADCSSL = ADCSSL_SETTING; // Set which analog pins are scanned // // _ADIF = 0; // _ADIP = 6; // This needs to be higher priority than the CAN interrupt (Which defaults to 4) // _ADIE = 1; // _ADON = 1; // // ----------------- UART #1 Setup and Data Buffer -------------------------// // Setup the UART input and output buffers uart1_input_buffer.write_location = 0; uart1_input_buffer.read_location = 0; uart1_output_buffer.write_location = 0; uart1_output_buffer.read_location = 0; ETMmodbus_put_index = 0; ETMmodbus_get_index = 0; U1MODE = MODBUS_U1MODE_VALUE; U1BRG = MODBUS_U1BRG_VALUE; U1STA = MODBUS_U1STA_VALUE; _U1TXIF = 0; // Clear the Transmit Interrupt Flag _U1TXIE = 1; // Enable Transmit Interrupts _U1RXIF = 0; // Clear the Recieve Interrupt Flag // _U1RXIE = 1; // Enable Recieve Interrupts U1MODEbits.UARTEN = 1; // And turn the peripheral on PIN_RS485_ENABLE = 1; //#ifdef __CAN_ENABLED // Initialize the Can module ETMCanSlaveInitialize(CAN_PORT_2, FCY_CLK, ETM_CAN_ADDR_GUN_DRIVER_BOARD, _PIN_RC4, 4, _PIN_RC3, _PIN_RC3); ETMCanSlaveLoadConfiguration(36772, BOARD_DASH_NUMBER, FIRMWARE_AGILE_REV, FIRMWARE_BRANCH, FIRMWARE_MINOR_REV); //#endif ETMDigitalInitializeInput(&global_data_A36772.switch_bit_0, 0, 50); ETMDigitalInitializeInput(&global_data_A36772.switch_bit_1, 0, 50); ETMDigitalInitializeInput(&global_data_A36772.switch_bit_2, 0, 50); ETMDigitalInitializeInput(&global_data_A36772.switch_bit_3, 0, 50); // Turn on switch bit pullups PIN_CPU_SWITCH_BIT0_ENABLE = OLL_STATUS_ACTIVE; PIN_CPU_SWITCH_BIT1_ENABLE = OLL_STATUS_ACTIVE; PIN_CPU_SWITCH_BIT2_ENABLE = OLL_STATUS_ACTIVE; PIN_CPU_SWITCH_BIT3_ENABLE = OLL_STATUS_ACTIVE; }
void InitializeA36582(void) { unsigned int pulse_data_A[7]; unsigned int pulse_data_B[7]; unsigned char analog_port_internal_adc; unsigned char analog_port_external_adc; // Initialize the status register and load the inhibit and fault masks _CONTROL_REGISTER = 0; _FAULT_REGISTER = 0; _WARNING_REGISTER = 0; _NOT_LOGGED_REGISTER = 0; // Configure Trigger Interrupt _INT1IP = 7; // This must be the highest priority interrupt _INT1IE = 1; // Configure the "False Trigger" Interrupt _INT3IP = 6; // This must be the highest priority interrupt _INT3EP = 0; // Positive Transition _INT3IE = 1; // By Default, the can module will set it's interrupt Priority to 4 // Initialize all I/O Registers TRISA = A36582_TRISA_VALUE; TRISB = A36582_TRISB_VALUE; TRISC = A36582_TRISC_VALUE; TRISD = A36582_TRISD_VALUE; TRISF = A36582_TRISF_VALUE; TRISG = A36582_TRISG_VALUE; // Initialize TMR2 TMR2 = 0; _T2IF = 0; T2CON = T2CON_VALUE; // Initialize TMR3 PR3 = PR3_VALUE_10_MILLISECONDS; TMR3 = 0; _T3IF = 0; T3CON = T3CON_VALUE; // Initialize the External EEprom ETMEEPromUseExternal(); ETMEEPromConfigureExternalDevice(EEPROM_SIZE_8K_BYTES, FCY_CLK, 400000, EEPROM_I2C_ADDRESS_0, 1); if (ETMEEPromCheckOK() == 0) { global_data_A36582.external_eeprom_error = 1; analog_port_internal_adc = ANALOG_INPUT_NO_CALIBRATION; analog_port_external_adc = ANALOG_INPUT_NO_CALIBRATION; } else { global_data_A36582.external_eeprom_error = 0; analog_port_internal_adc = ANALOG_INPUT_0; analog_port_external_adc = ANALOG_INPUT_1; } // Initialize the Can module ETMCanSlaveInitialize(CAN_PORT_1, FCY_CLK, ETM_CAN_ADDR_MAGNETRON_CURRENT_BOARD, _PIN_RG13, 4, _PIN_RA7, _PIN_RG12); ETMCanSlaveLoadConfiguration(36582, 251, FIRMWARE_AGILE_REV, FIRMWARE_BRANCH, FIRMWARE_BRANCH_REV); // Initialize the Analog input data structures ETMAnalogInitializeInput(&global_data_A36582.imag_internal_adc, MACRO_DEC_TO_SCALE_FACTOR_16(.25075), OFFSET_ZERO, analog_port_internal_adc, NO_OVER_TRIP, NO_UNDER_TRIP, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36582.imag_external_adc, MACRO_DEC_TO_SCALE_FACTOR_16(.25075), OFFSET_ZERO, analog_port_external_adc, NO_OVER_TRIP, NO_UNDER_TRIP, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER, NO_COUNTER); ETMAnalogInitializeInput(&global_data_A36582.analog_input_5v_mon, MACRO_DEC_TO_SCALE_FACTOR_16(.12500), OFFSET_ZERO, ANALOG_INPUT_NO_CALIBRATION, PWR_5V_OVER_FLT, PWR_5V_UNDER_FLT, NO_TRIP_SCALE, NO_FLOOR, NO_COUNTER, NO_COUNTER); // Configure SPI port, used by External ADC ConfigureSPI(ETM_SPI_PORT_2, ETM_DEFAULT_SPI_CON_VALUE, ETM_DEFAULT_SPI_CON2_VALUE, ETM_DEFAULT_SPI_STAT_VALUE, SPI_CLK_2_MBIT, FCY_CLK); //Initialize the internal ADC for Startup Power Checks // ---- Configure the dsPIC ADC Module ------------ // ADPCFG = ADPCFG_SETTING; // Set which pins are analog and which are digital I/O ADCON1 = ADCON1_SETTING_STARTUP; // Configure the high speed ADC module based on H file parameters ADCON2 = ADCON2_SETTING_STARTUP; // Configure the high speed ADC module based on H file parameters ADCON3 = ADCON3_SETTING_STARTUP; // Configure the high speed ADC module based on H file parameters ADCHS = ADCHS_SETTING_STARTUP; // Configure the high speed ADC module based on H file parameters //ADCSSL = ADCSSL_SETTING_STARTUP; _ADIF = 0; _ADON = 1; while (_ADIF == 0); // Wait for 16 ADC conversions to complete; _ADON = 0; global_data_A36582.analog_input_5v_mon.filtered_adc_reading = ADCBUF0 + ADCBUF1 + ADCBUF2 +ADCBUF3 + ADCBUF4 + ADCBUF5 + ADCBUF6 + ADCBUF7; global_data_A36582.analog_input_5v_mon.filtered_adc_reading += ADCBUF8 + ADCBUF9 + ADCBUFA +ADCBUFB + ADCBUFC + ADCBUFD + ADCBUFE + ADCBUFF; ETMAnalogScaleCalibrateADCReading(&global_data_A36582.analog_input_5v_mon); if (ETMAnalogCheckOverAbsolute(&global_data_A36582.analog_input_5v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; // DPARKER use the self test bits } if (ETMAnalogCheckUnderAbsolute(&global_data_A36582.analog_input_5v_mon)) { _CONTROL_SELF_CHECK_ERROR = 1; // DPARKER use the self test bits } ADCON1 = ADCON1_SETTING_OPERATE; // Configure the high speed ADC module based on H file parameters ADCON2 = ADCON2_SETTING_OPERATE; // Configure the high speed ADC module based on H file parameters ADCON3 = ADCON3_SETTING_OPERATE; // Configure the high speed ADC module based on H file parameters ADCHS = ADCHS_SETTING_OPERATE; // Configure the high speed ADC module based on H file parameters //ADCSSL = ADCSSL_SETTING_STARTUP; _ADIF = 0; _ADON = 1; _SAMP = 1; // Read Data from EEPROM if (global_data_A36582.external_eeprom_error == 0) { // Only read from the EEPROM if we can connect to it succesfully ETMEEPromReadPage(PULSE_COUNT_REGISTER_A, 7, &pulse_data_A[0]); ETMEEPromReadPage(PULSE_COUNT_REGISTER_B, 7, &pulse_data_B[0]); // If the data checks out, update with data if (pulse_data_A[6] == ETMCRCModbus(pulse_data_A, 12)) { global_data_A36582.arc_total = *(unsigned long*)&pulse_data_A[0]; global_data_A36582.pulse_total = *(unsigned long long*)&pulse_data_A[2]; } else if (pulse_data_B[6] == ETMCRCModbus(pulse_data_B, 12)) { global_data_A36582.arc_total = *(unsigned long*)&pulse_data_B[0]; global_data_A36582.pulse_total = *(unsigned long long*)&pulse_data_B[2]; } else { // Both EEPROM Registers were corrupted global_data_A36582.arc_total = 0; //global_data_A36582.arc_total |= 0x00000000; // Set the highest bit high to indicate an EEPROM reading error global_data_A36582.pulse_total = 0; //global_data_A36582.pulse_total |= 0x0000000000000000; // Set the highest bit high to indicate an EEPROM reading error } } else { // There is an EEPROM Error, use values that we can use to interpret global_data_A36582.arc_total = 0; //global_data_A36582.arc_total |= 0x00000000; // Set the highest bit high to indicate an EEPROM reading error global_data_A36582.pulse_total = 0; //global_data_A36582.pulse_total = 0x0000000000000000; // Set the highest bit high to indicate an EEPROM reading error } // Run a dummy conversion _SAMP = 0; }
void main(void) { char TempVar; // variable used for IMU chip Autotest unsigned char IMUAutotestResult; // structure used to store IMU data struct IMUData CurrentIMUData; // variable for CAN TX FIFO buffer struct CANTxMsg TempCANTxMsg; // variable for CAN RX FIFO buffer struct CANRxMsg TempCANRxMsg; //---------------------------------------------------- //---------- CPU internal configurations: ----------- //---------------------------------------------------- CLRWDT(); // clear watchdog timer at startup /* Configure the oscillator for the CPU */ ConfigureOscillator(); __delay_ms(10); // wait for Oscillator to be stabilized // configure CPU GPIO for IMU board ConfigureGPIO(); //USART Initialize(); ConfigureUSART1(); ConfigureUSART2(); // SPI initialize ConfigureSPI(); //CAN controller Initialize ECANInitialize(); //Set MASK and Filters for CAN ECANFiltersInit(); // Timers configuration ConfigureTimers(); //---------------------------------------------------- //---------- Global variables initialisation -------- //---------------------------------------------------- // tick counter initialisation TickCounter.AccelTick_ms=0; TickCounter.GyroTick_ms=1; TickCounter.MagnetTick_ms=2; // initialize CAN tx FIFO CANTxFifoInit(); CANRxFifoInit(); // initialise USART RX FIFO's USARTFifoInit (); //---------------------------------------------------- //------ external peripheral configurations: -------- //---------------------------------------------------- __delay_ms(10); // wait for reset to be released on external peripherals ISM_RESET = 0; // release reset of ISM module IMUInitRegisters(); // init of BMX055 chip IMUAutotestResult=IMUAutotest(); // launch IMU autotest //---------------------------------------------------- //---------- GSM startup delay ----------- //---------------------------------------------------- GSM_RTS=1; for(char i=0;i<200;i++) { __delay_ms(10); CLRWDT(); // clear watchdog timer each loop } GSM_RTS=0; __delay_ms(10); __delay_ms(10); //---------------------------------------------------- //---------- Ready to go in main loop: ----------- //---------- interrupts activation ----------- //---------------------------------------------------- ConfigureInterrupts(); LED1=1; // everything is initialized: enable the PWR/booted LED //---------------------------------------------------- //---------- GSM dummy AT command ----------- //---------------------------------------------------- USART1Write('A'); USART1Write('T'); USART1Write(0x0D); for(char i=0;i<10;i++) { __delay_ms(10); } //----------------------------------------------------- //------------- infinite main loop ---------- //---------------------------------------------------- while(1) { //-------------------------------------------------------------------------------- //------------- periodic tasks occures according to TickCounter variable---------- //-------------------------------------------------------------------------------- if(TickCounter.AccelTick_ms>IMU_TICK_PERIOD) { CLRWDT(); // clear watchdog timer each real time cycles LED2=1; TickCounter.AccelTick_ms=0; // reset IMU tick counter to 0 CurrentIMUData = IMUUpdateData(); // update IMU data from sensor // send Accelerometer data to CAN Fifo TempCANTxMsg.data_TX[0]=(char)(CurrentIMUData.XAccelerationData>>8); //fill data buffer TempCANTxMsg.data_TX[1]=(char)(CurrentIMUData.XAccelerationData); TempCANTxMsg.data_TX[2]=(char)(CurrentIMUData.YAccelerationData>>8); TempCANTxMsg.data_TX[3]=(char)(CurrentIMUData.YAccelerationData); TempCANTxMsg.data_TX[4]=(char)(CurrentIMUData.ZAccelerationData>>8); TempCANTxMsg.data_TX[5]=(char)(CurrentIMUData.ZAccelerationData); TempCANTxMsg.data_TX[6]=0; TempCANTxMsg.data_TX[7]=0; TempCANTxMsg.dataLen= ACCEL_DATA_MESSAGE_LEN; TempCANTxMsg.id = (CAN_MESSAGE_IMU_TYPE << 7 | CAN_DEVICE_ADRESS <<4 | ACCEL_DATA_MESSAGE_ADRESS ); TempCANTxMsg.flags = ECAN_TX_STD_FRAME; if(!CANTxFifo.Fifofull) PutCANTxFifo(TempCANTxMsg); LED2=0; } if(TickCounter.GyroTick_ms>IMU_TICK_PERIOD) { //LED2=1; TickCounter.GyroTick_ms=0; // reset IMU tick counter to 0 // send Gyro data to CAN Fifo TempCANTxMsg.data_TX[0]=(char)(CurrentIMUData.XGyroscopeData>>8); TempCANTxMsg.data_TX[1]=(char)(CurrentIMUData.XGyroscopeData); TempCANTxMsg.data_TX[2]=(char)(CurrentIMUData.YGyroscopeData>>8); TempCANTxMsg.data_TX[3]=(char)(CurrentIMUData.YGyroscopeData); TempCANTxMsg.data_TX[4]=(char)(CurrentIMUData.ZGyroscopeData>>8); TempCANTxMsg.data_TX[5]=(char)(CurrentIMUData.ZGyroscopeData); TempCANTxMsg.dataLen= GYRO_DATA_MESSAGE_LEN; TempCANTxMsg.id = (CAN_MESSAGE_IMU_TYPE << 7 | CAN_DEVICE_ADRESS <<4 | GYRO_DATA_MESSAGE_ADRESS ); TempCANTxMsg.flags = ECAN_TX_STD_FRAME; if(!CANTxFifo.Fifofull) PutCANTxFifo(TempCANTxMsg); }