bool Board_PDM_Status_Update(PDM_STATUS_T *pdm_status, uint8_t *i2c_rx_buffer, bool cs) { int tmp; uint32_t battery_voltage_mVolts, battery_charge_percent; int32_t battery_current_mAmps; tmp = Chip_I2C_MasterCmdRead(DEFAULT_I2C, I2C_GG_SLAVE_ADDRESS, I2C_GG_VOLT_REG, i2c_rx_buffer, 2); //Read raw voltage data from gas gauge battery_voltage_mVolts = ((uint16_t)i2c_rx_buffer[0] << 8) | (uint16_t)i2c_rx_buffer[1]; //Convert two bytes to hex battery_voltage_mVolts = 23600*battery_voltage_mVolts/0xFFFF; //Convert to milliVolts Board_UART_Print("Voltage Data (mV): "); Board_UART_PrintNum(battery_voltage_mVolts, 10, false); Board_UART_Print(" Length: "); Board_UART_PrintNum(tmp, 10, true); tmp = Chip_I2C_MasterCmdRead(DEFAULT_I2C, I2C_GG_SLAVE_ADDRESS, I2C_GG_CHRG_REG, i2c_rx_buffer, 2); //Read raw charge data from gas gauge battery_charge_percent = ((uint16_t)i2c_rx_buffer[0] << 8) | (uint16_t)i2c_rx_buffer[1]; //Convert two bytes to hex battery_charge_percent = 100*battery_charge_percent/0xFFFF; //Convert to percentage charged Board_UART_Print("Accumulated Charge Data (%): "); Board_UART_PrintNum(battery_charge_percent, 10, false); Board_UART_Print(" Length: "); Board_UART_PrintNum(tmp, 10, true); tmp = Chip_I2C_MasterCmdRead(DEFAULT_I2C, I2C_GG_SLAVE_ADDRESS, I2C_GG_CURR_REG, i2c_rx_buffer, 2); //Read raw current data from gas gauge battery_current_mAmps = ((uint16_t)i2c_rx_buffer[0] << 8) | (uint16_t)i2c_rx_buffer[1]; //Convert two bytes to hex battery_current_mAmps = 60*(battery_current_mAmps-0x7FFF)*1000/(50*0x7FFF); //Convert to milliAmps Board_UART_Print("Current Data (mA): "); if(battery_current_mAmps < 0) { battery_current_mAmps = battery_current_mAmps * -1; Board_UART_Print("-"); } Board_UART_PrintNum(battery_current_mAmps, 10, false); Board_UART_Print(" Length: "); Board_UART_PrintNum(tmp, 10, true); //Update the correct system struct if(cs) { //Update the critical systems PDM struct pdm_status->critical_systems_bus_battery = battery_voltage_mVolts < LOW_VOLTAGE_THRESHOLD; pdm_status->critical_systems_dc_dc = battery_current_mAmps >= 0; Board_UART_Println("Critical Systems Check"); Board_UART_Println(""); } else { //Update the low voltage systems PDM struct pdm_status->low_voltage_bus_battery = battery_voltage_mVolts < LOW_VOLTAGE_THRESHOLD; pdm_status->low_voltage_dc_dc = battery_current_mAmps >= 0; Board_UART_Println("Low Voltage Systems Check"); Board_UART_Println(""); } return tmp == 2; }
/* Read data from UDA register */ uint16_t UDA1380_REG_Read(uint8_t reg) { uint8_t rx_data[2]; if (Chip_I2C_MasterCmdRead(UDA1380_I2C_BUS, I2CDEV_UDA1380_ADDR, reg, rx_data, 2) == 2) { return (rx_data[0] << 8) | rx_data[1]; } return 0; }
/* Read data from UDA register */ uint16_t WM8904_REG_Read(uint8_t reg) { uint8_t rx_data[2]; if (Chip_I2C_MasterCmdRead(WM8904_I2C_BUS, I2CDEV_WM8904_ADDR, reg, rx_data, 2) == 2) { return (rx_data[0] << 8) | rx_data[1]; } return 0; }
/* Multiple value verification function */ int UDA1380_REG_VerifyMult(uint8_t reg, const uint8_t *value, uint8_t *buff, int len) { int i; if (Chip_I2C_MasterCmdRead(UDA1380_I2C_BUS, I2CDEV_UDA1380_ADDR, reg, buff, len) != len) { return 0; /* Partial read */ } /* Compare the values */ for (i = 0; i < len; i++) { if (value[i] != buff[i]) { break; } } return i == len; }
uint32_t Board_I2C_Master_WriteCmdAdnRead(uint8_t slaveAddr, uint8_t cmd,uint8_t *buff, int len) { return Chip_I2C_MasterCmdRead(I2C0, slaveAddr, cmd, buff, len); }
int main(void) { //--------------- // Initialize SysTick Timer to generate millisecond count if (Board_SysTick_Init()) { // Unrecoverable Error. Hang. while(1); } //--------------- // Initialize GPIO and LED as output Board_LEDs_Init(); Board_LED_On(LED0); Board_LED_On(LED1); Board_LED_On(LED2); Board_LED_On(LED3); //Initialize I2C Board_I2C_Init(); //--------------- // Initialize UART Communication Board_UART_Init(UART_BAUD_RATE); Board_UART_Println("Started up"); //--------------- // Initialize CAN and CAN Ring Buffer RingBuffer_Init(&can_rx_buffer, _rx_buffer, sizeof(CCAN_MSG_OBJ_T), BUFFER_SIZE); RingBuffer_Flush(&can_rx_buffer); Board_CAN_Init(CCAN_BAUD_RATE, CAN_rx, CAN_tx, CAN_error); // For your convenience. // typedef struct CCAN_MSG_OBJ { // uint32_t mode_id; // uint32_t mask; // uint8_t data[8]; // uint8_t dlc; // uint8_t msgobj; // } CCAN_MSG_OBJ_T; /* [Tutorial] How do filters work? Incoming ID & Mask == Mode_ID for msgobj to accept message Incoming ID : 0xabc Mask: 0xF0F & ----------- 0xa0c mode_id == 0xa0c for msgobj to accept message */ //Set mask to only accept messages from Driver Interface msg_obj.msgobj = 1; msg_obj.mode_id = DI_PACKET__id; msg_obj.mask = 0x555; LPC_CCAN_API->config_rxmsgobj(&msg_obj); can_error_flag = false; can_error_info = 0; lastPrint = msTicks; PDM_STATUS_T pdm_status; int tmp; bool lv_i2c = true, cs_i2c = true, mux_i2c = true; //Board_I2C_Reset(I2C_GG_CONTINUOUS, i2c_tx_buffer); //Open I2C Channel 0 i2c_tx_buffer[0] = I2C_MUX_CHANNEL_0; tmp = Chip_I2C_MasterSend(DEFAULT_I2C, I2C_MUX_SLAVE_ADDRESS, i2c_tx_buffer, 1); Board_UART_Print("Opened Channel 0: "); Board_UART_PrintNum(tmp, 10, true); //Set Gas Gauge 0 to continuous data collection i2c_tx_buffer[0] = I2C_GG_CTRL_REG; i2c_tx_buffer[1] = I2C_GG_CONTINUOUS; tmp = Chip_I2C_MasterSend(DEFAULT_I2C, I2C_GG_SLAVE_ADDRESS, i2c_tx_buffer, 2); Board_UART_Print("Set I2C0 to continuous data collection: "); Board_UART_PrintNum(tmp, 10, true); //Open I2C Channel 1 i2c_tx_buffer[0] = I2C_MUX_CHANNEL_1; tmp = Chip_I2C_MasterSend(DEFAULT_I2C, I2C_MUX_SLAVE_ADDRESS, i2c_tx_buffer, 1); Board_UART_Print("Opened Channel 1: "); Board_UART_PrintNum(tmp, 10, true); //Set Gas Gauge 1 to continuous data collection i2c_tx_buffer[0] = I2C_GG_CTRL_REG; i2c_tx_buffer[1] = I2C_GG_CONTINUOUS; tmp = Chip_I2C_MasterSend(DEFAULT_I2C, I2C_GG_SLAVE_ADDRESS, i2c_tx_buffer, 2); Board_UART_Print("Set I2C1 to continuous data collection: "); Board_UART_PrintNum(tmp, 10, true); while (1) { //Set PDM status based on CAN messages from Driver Interface if (!RingBuffer_IsEmpty(&can_rx_buffer)) { CCAN_MSG_OBJ_T temp_msg; RingBuffer_Pop(&can_rx_buffer, &temp_msg); //Test for DI OFF or SHUTDOWN IMPENDING message if((temp_msg.data[3] << 8 | temp_msg.data[2]) == ____DI_PACKET__DRIVE_STATUS__SHUTDOWN_IMPENDING || (temp_msg.data[3] << 8 | temp_msg.data[2]) == ____DI_PACKET__DRIVE_STATUS__OFF) { if(pdm_status.pdm_on) { pdm_status.pdm_on = false; Board_LED_Off(LED0); Board_I2C_Reset(I2C_GG_SLEEP, i2c_tx_buffer); } } else { if(!(pdm_status.pdm_on)) { pdm_status.pdm_on = true; Board_LED_On(LED0); Board_I2C_Reset(I2C_GG_CONTINUOUS, i2c_tx_buffer); } } } //Reset gas gauge 0 if it has been diconnected and then reconnected to power i2c_tx_buffer[0] = I2C_MUX_CHANNEL_0; tmp = Chip_I2C_MasterSend(DEFAULT_I2C, I2C_MUX_SLAVE_ADDRESS, i2c_tx_buffer, 1); //Open I2C Channel 0 tmp = Chip_I2C_MasterCmdRead(DEFAULT_I2C, I2C_GG_SLAVE_ADDRESS, I2C_GG_CTRL_REG, i2c_rx_buffer, 1); Board_UART_PrintNum(i2c_rx_buffer[0],16,true); if((uint16_t)i2c_rx_buffer[0] == I2C_GG_DEFAULT) { //Test for default values in control register if(pdm_status.pdm_on) { Board_I2C_Reset(I2C_GG_CONTINUOUS, i2c_tx_buffer); } else { Board_I2C_Reset(I2C_GG_SLEEP, i2c_tx_buffer); } //Send a heartbeat with a com error Board_CAN_SendHeartbeat(&pdm_status, &msg_obj, true); } //Reset gas gauge 1 if it has been diconnected and then reconnected to power i2c_tx_buffer[0] = I2C_MUX_CHANNEL_1; tmp = Chip_I2C_MasterSend(DEFAULT_I2C, I2C_MUX_SLAVE_ADDRESS, i2c_tx_buffer, 1); //Open 12C Channel 1 tmp = Chip_I2C_MasterCmdRead(DEFAULT_I2C, I2C_GG_SLAVE_ADDRESS, I2C_MUX_CHANNEL_0, i2c_rx_buffer, 1); Board_UART_PrintNum(i2c_rx_buffer[0],16,true); if((uint16_t)i2c_rx_buffer[0] == I2C_GG_DEFAULT) { //Test for default values in control register if(pdm_status.pdm_on) { Board_I2C_Reset(I2C_GG_CONTINUOUS, i2c_tx_buffer); } else { Board_I2C_Reset(I2C_GG_SLEEP, i2c_tx_buffer); } //Send a heartbeat with a com error Board_CAN_SendHeartbeat(&pdm_status, &msg_obj, true); } /* Update PDM and Debug LED code */ //Attempt to open I2C Channel 0 i2c_tx_buffer[0] = I2C_MUX_CHANNEL_0; mux_i2c = Chip_I2C_MasterSend(DEFAULT_I2C, I2C_MUX_SLAVE_ADDRESS, i2c_tx_buffer, 1); //Attempt to update Critical Systems PDM Struct cs_i2c = Board_PDM_Status_Update(&pdm_status, i2c_rx_buffer, true); //Attempt to open I2C Channel 1 i2c_tx_buffer[0] = I2C_MUX_CHANNEL_1; mux_i2c = Chip_I2C_MasterSend(DEFAULT_I2C, I2C_MUX_SLAVE_ADDRESS, i2c_tx_buffer, 1); //Attempt to update Low Voltage PDM struct lv_i2c = Board_PDM_Status_Update(&pdm_status, i2c_rx_buffer, false); //Run debug logic and update state Board_PDM_Status_Debug(&pdm_status, mux_i2c, cs_i2c, lv_i2c); if(msTicks - lastPrint > FREQ_THRESHOLD){ // 10 times per second lastPrint = msTicks; // Store the current time, to allow the process to be done in another 1/10 seconds Board_CAN_SendHeartbeat(&pdm_status, &msg_obj, false); } } }