TLMoto

Dependencies:   CANnucleo CANnucleo_Hello LTC68041 mbed

Fork of CANnucleo_Hello by Zoltan Hudak

Revision:
21:988413f53fbe
Parent:
20:eb1a8042605e
--- a/main.cpp	Tue Aug 16 21:13:47 2016 +0000
+++ b/main.cpp	Sat Oct 22 16:34:06 2016 +0000
@@ -1,131 +1,324 @@
-/*
- * An example showing how to use the CANnucleo library:
- *
- * Two affordable (less than $3 on ebay) STM32F103C8T6 boards (20kB SRAM, 64kB Flash), 
- * (see [https://developer.mbed.org/users/hudakz/code/STM32F103C8T6_Hello/] for more details) 
- * are connected to the same CAN bus via transceivers (MCP2551 or TJA1040, or etc.). 
- * CAN transceivers are not part of NUCLEO boards, therefore must be added by you. 
- * Remember also that CAN bus (even a short one) must be terminated with 120 Ohm resitors at both ends.
- *
- * For more details see the wiki page <https://developer.mbed.org/users/hudakz/code/CANnucleo_Hello/>
- *
- * NOTE: If you'd like to use the official NUCLEO boards comment out line 22
- *
- * The same code is used for both NUCLEO boards, but:
- *      For board #1 compile the example without any change.
- *      For board #2 comment out line 23 before compiling 
- *
- * Once the binaries have been downloaded to the boards reset board #1.
- *
- */ 
-
-//#define TARGET_STM32F103C8T6  1     // uncomment this line when using STM32F103C8T6 boards!                                    
-#define BOARD1                1     // comment out this line when compiling for board #2
-
-#if defined(TARGET_STM32F103C8T6)
-    #define LED_PIN PC_13
-    const int OFF = 1;
-    const int ON  = 0;
-#else
-    #define LED_PIN LED1
-    const int OFF = 0;
-    const int ON  = 1;
-#endif
-
-#if defined(BOARD1)
-    const unsigned int RX_ID = 0x100;
-    const unsigned int TX_ID = 0x101;
-#else
-    const unsigned int RX_ID = 0x101;
-    const unsigned int TX_ID = 0x100;
-#endif
-
 #include "CANnucleo.h"
 #include "mbed.h"
+#include "LTC68041.h"
 
-/* 
- * To avaoid name collision with the CAN and CANMessage classes built into the mbed library
- * the CANnucleo's CAN and CANMessage classes have been moved into the CANnucleo namespace.
- * Remember to qualify them with the CANnucleo namespace.
- */
+
+
+uint8_t const TOTAL_IC = 1;//!<number of ICs in the daisy chain
+
+uint8_t rx_cfg[TOTAL_IC][8];
+uint8_t tx_cfg[TOTAL_IC][6];
+uint16_t aux_codes[TOTAL_IC][6];
+uint16_t cell_codes[TOTAL_IC][12];
+volatile bool           msgAvailable = false;
+volatile bool           to_send = false;
 CANnucleo::CAN          can(PA_11, PA_12);  // CAN Rx pin name, CAN Tx pin name
 CANnucleo::CANMessage   rxMsg;
 CANnucleo::CANMessage   txMsg;
-DigitalOut              led(LED_PIN);
-int                     ledState;
-Timer                   timer;
-int                     counter = 0;
-volatile bool           msgAvailable = false;
+DigitalOut              led(PA_5);
+/*!***********************************
+\brief Initializes the configuration array
+**************************************/
+void init_cfg()
+{
+    for (int i = 0; i<TOTAL_IC; i++) {
+        tx_cfg[i][0] = 0xFE;
+        tx_cfg[i][1] = 0x00 ;
+        tx_cfg[i][2] = 0x00 ;
+        tx_cfg[i][3] = 0x00 ;
+        tx_cfg[i][4] = 0x00 ;
+        tx_cfg[i][5] = 0x00 ;
+    }
+}
+void serial_print_hex(uint8_t data)
+{
+    if (data< 16) {
+        printf("0");
+        printf("%x",(uint8_t)data);
+    } else
+        printf("%x",(uint8_t)data);
+}
+void print_config()
+{
+    int cfg_pec;
+    printf("Written Configuration:\n\r ");
+    for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++) {
+        printf(" IC ");
+        printf("%d", current_ic+1);
+        printf(": ");
+        printf("0x");
+        serial_print_hex(tx_cfg[current_ic][0]);
+        printf(", 0x");
+        serial_print_hex(tx_cfg[current_ic][1]);
+        printf(", 0x");
+        serial_print_hex(tx_cfg[current_ic][2]);
+        printf(", 0x");
+        serial_print_hex(tx_cfg[current_ic][3]);
+        printf(", 0x");
+        serial_print_hex(tx_cfg[current_ic][4]);
+        printf(", 0x");
+        serial_print_hex(tx_cfg[current_ic][5]);
+        printf(", Calculated PEC: 0x");
+        cfg_pec = pec15_calc(6,&tx_cfg[current_ic][0]);
+        serial_print_hex((uint8_t)(cfg_pec>>8));
+        printf(", 0x");
+        serial_print_hex((uint8_t)(cfg_pec));
+    }
+    printf("\n\r");
+}
+
+void print_rxconfig()
+{
+    printf("Received Configuration ");
+    for (int current_ic=0; current_ic<TOTAL_IC; current_ic++) {
+        printf(" IC ");
+        printf("%d " ,current_ic+1);
+        printf(": 0x");
+        serial_print_hex(rx_cfg[current_ic][0]);
+        printf(", 0x");
+        serial_print_hex(rx_cfg[current_ic][1]);
+        printf(", 0x");
+        serial_print_hex(rx_cfg[current_ic][2]);
+        printf(", 0x");
+        serial_print_hex(rx_cfg[current_ic][3]);
+        printf(", 0x");
+        serial_print_hex(rx_cfg[current_ic][4]);
+        printf(", 0x");
+        serial_print_hex(rx_cfg[current_ic][5]);
+        printf(", Received PEC: 0x");
+        serial_print_hex(rx_cfg[current_ic][6]);
+        printf(", 0x");
+        serial_print_hex(rx_cfg[current_ic][7]);
+    }
+}
+int err;
+void print_cells2()
+{
+
+    for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) {
+
+        for (int i=0; i<12; i++) {
+            printf(" C");
+            printf("%d",i+1);
+            printf(":");
+            printf("%f", cell_codes[current_ic][i]*0.0001);
+            printf(",");
+        }
 
-/**
- * @brief   'CAN receive-complete' interrup handler.
- * @note    Called on arrival of new CAN message.
- *          Keep it as short as possible.
- * @param   
- * @retval  
- */
-void onMsgReceived() {
+    }
+}
+void pec_error()
+{
+    for(int i = 0; i<5; i++) {
+        led = 1;
+        wait(0.2);
+        led=0;
+        wait(0.2);
+    }
+}
+char cells_left=0;
+Ticker ticker;
+Ticker sender;
+
+typedef union can_union {
+    int i[2];
+    char bytes[8];
+    float f[2];
+} data;
+
+void message_trigger()
+{
+    if(cells_left < 1) {
+        sender.detach();
+    } else {
+
+
+        to_send = 1;
+    }
+
+}
+
+void check_charging_voltage()
+{
+    wakeup_idle();
+    __disable_irq();
+    LTC6804_adcv();
+    __enable_irq();
+    wait_ms(10);
+    wakeup_idle();
+    __enable_irq();
+    err = LTC6804_rdcv(0, TOTAL_IC,cell_codes);
+    __disable_irq();
+    if (err == -1) {
+        pec_error();
+    }
+    for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) {
+        for (int i=0; i<12; i++) {
+            if(cell_codes[current_ic][i]*0.0001  > 3.85) {
+                switch (i) {
+                    case 0:
+                        tx_cfg[0][4] = tx_cfg[0][4] | 0x01 ;
+                    case 1:
+                        tx_cfg[0][4] = tx_cfg[0][4] | 0x02 ;
+                    case 2:
+                        tx_cfg[0][4] = tx_cfg[0][4] | 0x04 ;
+                    case 3:
+                        tx_cfg[0][4] = tx_cfg[0][4] | 0x08 ;
+                    case 4:
+                        tx_cfg[0][4] = tx_cfg[0][4] | 0x10 ;
+                    case 5:
+                        tx_cfg[0][4] = tx_cfg[0][4] | 0x20 ;
+                    case 6:
+                        tx_cfg[0][4] = tx_cfg[0][4] | 0x40 ;
+                    case 7:
+                        tx_cfg[0][4] = tx_cfg[0][4] | 0x80;
+                    case 8:
+                        tx_cfg[0][5] = tx_cfg[0][5] | 0x01;
+                    case 9:
+                        tx_cfg[0][5] = tx_cfg[0][5] | 0x10;
+                }
+            }
+        }
+    }
+    //print_cells2();
+    __disable_irq();
+    LTC6804_wrcfg(TOTAL_IC,tx_cfg);
+    __enable_irq();
+}
+
+
+
+void check_discharging_voltage()
+{
+    wakeup_idle();
+    LTC6804_adcv();
+
+    wait_ms(10);
+    wakeup_idle();
+    err = LTC6804_rdcv(0, TOTAL_IC,cell_codes);
+    if (err == -1) {
+        pec_error();
+    }/*
+    for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) {
+        for (int i=0; i<11; i++) {
+            //printf("%f\t", cell_codes[current_ic][i]*0.0001);
+            if(cell_codes[current_ic][i]*0.0001  < 2.7) {
+                txMsg.clear();
+                txMsg.id = 1;
+                printf("%f\t", cell_codes[current_ic][i]*0.0001);
+
+                txMsg << cell_codes[current_ic][i]*0.0001;
+                can.write(txMsg);
+                wait(0.1);
+            }
+        }
+    }*/
+    //print_cells2();
+    cells_left = 12;
+
+//print_cells2();
+    LTC6804_wrcfg(TOTAL_IC,tx_cfg);
+}
+
+void onMsgReceived()
+{
     msgAvailable = true;
 }
 
-/**
- * @brief   Main
- * @note
- * @param 
- * @retval
- */
-int main() {
-    can.frequency(1000000);                     // set bit rate to 1Mbps
-    can.attach(&onMsgReceived);                 // attach 'CAN receive-complete' interrupt handler
-    
-#if defined(BOARD1)
-    led = ON;       // turn LED on
-    timer.start();  // start timer
-    printf("CANnucleo_Hello board #1\r\n");
-#else
-    led = OFF;      // turn LED off
-    printf("CANnucleo_Hello board #2\r\n");
-#endif
+
 
-    while(1) {
-        if(timer.read() >= 1.0) {               // check for timeout
-            timer.stop();                       // stop timer
-            timer.reset();                      // reset timer
-            counter++;                          // increment counter
-            ledState = led.read();              // get led state
-            txMsg.clear();                      // clear Tx message storage
-            txMsg.id = TX_ID;                   // set ID
-            txMsg << counter;                   // append first data item
-            txMsg << ledState;                  // append second data item (total data lenght must be <= 8 bytes!)
-            led = OFF;                          // turn LED off
-            if(can.write(txMsg))                // transmit message
-                printf("CAN message sent\r\n"); 
-            else
-                printf("Transmission error\r\n");
-        }
-        if(msgAvailable) {
-            msgAvailable = false;               // reset flag for next use
-            can.read(rxMsg);                    // read message into Rx message storage
-            printf("CAN message received\r\n");
-            printf("  ID      = 0x%.3x\r\n", rxMsg.id);
-            printf("  Type    = %d\r\n", rxMsg.type);
-            printf("  Format  = %d\r\n", rxMsg.format);
-            printf("  Length  = %d\r\n", rxMsg.len);
-            printf("  Data    =");            
-            for(int i = 0; i < rxMsg.len; i++)
-                printf(" %.2x", rxMsg.data[i]);
-            printf("\r\n");
-            // Filtering performed by software:           
-            if(rxMsg.id == RX_ID) {             // See comments in CAN.cpp for filtering performed by hardware
-                rxMsg >> counter;               // extract first data item
-                rxMsg >> ledState;              // extract second data item
-                printf("  counter = %d\r\n", counter);
-                led = ON;                       // turn LED on
-                timer.start();                  // transmission lag
-            }
-        }
+bool to_charge_or_not_to_charge=false;           // false = discharge
+bool charging = false;
+bool discharging = false;
+void monitor()
+{
+    led = !led;
+    if(to_charge_or_not_to_charge) {
+        charging = 1;
+        discharging = 0;
+    } else {
+        discharging = 1;
+        charging = 0;
     }
 }
 
 
+int main()
+{
+        data data;
 
+    //printf("starting\n\r");
+    led =1;
+    wait(1);
+    pec_error();
+    discharging = 1;
+
+    ticker.attach(&monitor, 5);
+    LTC6804_initialize();
+    init_cfg();
+//write configuration
+    wakeup_sleep();
+    __disable_irq();    // Disable Interrupts
+    LTC6804_wrcfg(TOTAL_IC,tx_cfg);
+    __enable_irq();
+    wait(1);
+//read configuration: may differ from written config
+    wakeup_sleep();
+    __disable_irq();
+    err = LTC6804_rdcfg(TOTAL_IC,rx_cfg);
+    __enable_irq();
+    if (err == -1) {
+        pec_error();
+    }
+    wait(0.5);
+
+    wakeup_idle();
+    __disable_irq();
+    LTC6804_adcv();
+    __enable_irq();
+    wait_ms(10);
+    wakeup_idle();
+    __disable_irq();
+    err = LTC6804_rdcv(0, TOTAL_IC,cell_codes);
+    __enable_irq();
+    if (err == -1) {
+        pec_error();
+    }
+    can.frequency(1000000);                     // set bit rate to 1Mbps
+    can.attach(&onMsgReceived);
+    //print_cells2();
+    while(1) {
+        if(charging) {
+            charging = 0;
+            check_charging_voltage();
+
+        }
+        if(discharging) {
+            discharging = 0;
+            check_discharging_voltage();
+            sender.attach(&message_trigger,0.1);
+        }
+        if(to_send) {
+            
+                
+            to_send=0;
+            txMsg.clear();
+            txMsg.id = 10;
+            txMsg.len = 5;
+            data.f[0] = cell_codes[0][cells_left-1]*0.0001;
+            txMsg.data[0] = data.bytes[0];
+            txMsg.data[1] = data.bytes[1];
+            txMsg.data[2] = data.bytes[2];
+            txMsg.data[3] = data.bytes[3];
+            txMsg.data[4] = cells_left;
+            cells_left--;
+            if(!(can.write(txMsg))) {
+                pec_error();
+                cells_left++;
+                //to_send=1;
+            }
+
+        }
+    }
+
+}