Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:c0bb943bc2a7, committed 2012-04-09
- Comitter:
- priusfan
- Date:
- Mon Apr 09 15:27:55 2012 +0000
- Commit message:
- todo: find a working BT module...
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MODSERIAL.lib Mon Apr 09 15:27:55 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/AjK/code/MODSERIAL/#af2af4c61c2f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/common.h Mon Apr 09 15:27:55 2012 +0000
@@ -0,0 +1,30 @@
+/*
+ * File: common.h
+ * Author: teamprii
+ *
+ * Created on April 8, 2012, 6:49 PM
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <vector>
+using namespace std;
+
+class reqTbl {
+public:
+ int id; // PID
+ int freq; // request frequency
+ int fcnt; // frequency counter
+ vector<int> code; // list of code; change from cod1, cod2 to a vector code and move to end of line in file for easier read
+ reqTbl();
+};
+
+reqTbl::reqTbl() {
+ fcnt = 0; // initialize frequency counter to 0
+}
+
+extern vector<reqTbl> reqTable;
+extern int reqNumTbl; // this will be just (int)reqTable.size()
+
+#endif /* COMMON_H */
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon Apr 09 15:27:55 2012 +0000
@@ -0,0 +1,607 @@
+/* this is a beta release for a can sequencer for prius gen3 on mbed
+it is based on a work from Moon Light on mbed.org for the sequencer
+and from Yoshi for the filtering
+
+
+
+harware:
+ mbed LPC1768
+ Can transceiver mcp2551 on pin 30 & 29
+ BT module BlueToothBee on pin 28 & 27
+
+main mods:
+ remove sd card (not used yet)
+ change structure for table.cpp: use cod1 & cod2 instead of code
+ change content in this table to follow only usefull request (known content)
+ install filters
+
+mod 2/04/2012: change detection for last frame in case of multiframe
+
+mod 9/04/2012:: use external files on /local/ for filters & requests * Author: teamprii
+
+priusfan @ priusfan.info
+
+*/
+
+
+#include "mbed.h"
+#include "MODSERIAL.h" // buffered serial
+#include "stdarg.h"
+#include "common.h"
+#include <iostream>
+#include <fstream>
+#include "sstream"
+DigitalOut myled(LED1);
+
+LocalFileSystem local("local");
+vector<reqTbl> reqTable;
+int reqNumTbl;
+
+
+
+
+Ticker ticker;
+Timer timer;
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+// We use can on mbed pins 29(CAN_TXD) and 30(CAN_RXD).
+CAN can2(p30, p29);
+
+MODSERIAL pc(USBTX, USBRX, 1000, 100); // tx, rx, txBuffer, rxBuffer
+
+MODSERIAL BT(p28, p27, 1000, 100); // tx, rx, txBuffer, rxBuffer
+
+
+
+
+
+
+int len_max = 0;
+
+// this request will be completely modified according external file /local/request.txt
+char msg_Request[] = { 0x02, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Request Data; 02 is the length of the qry
+
+char msg_Continue[] = { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Continue Receiving Additional Data
+int msg_ReqIdx = 0;
+int msg_ReqFrameW = 0;
+
+//
+char msg_MF_data[100] ; // used to store Multiframe
+int msg_MF_Idx ; // cursor for previous
+unsigned int msg_MF_Id ; // Multiframe Id
+
+char Crc ; // crc char for checking integrity
+
+
+
+//
+
+
+//============================================
+// declaration functions (prototypes)
+//============================================
+void init();
+int install_filters();
+int read_reqTable(vector<reqTbl>& reqtable, int& reqnumtbl);
+void CAN2_wrFilter (uint32_t id);
+void timchk();
+void can2rcv();
+//void calcs();
+//void calcm();
+//=======================================
+unsigned int prev_us = 0; // work
+unsigned int curr_us = 0; // micro sec looped
+unsigned int curr_uH = 0; // micro sec upper dword
+unsigned int diff_us = 0; // erapsed us
+unsigned int curr_ms = 0; // milli sec looped
+unsigned int left_ms = 0; // work
+unsigned int curr_sc = 0; // sec looped
+int ms_1000 = 0; // 1000 looped ms
+int ms_60000 = 0; // 60000 looped ms
+unsigned int max_diff = 0;
+int send_per_sec = 0;
+int rec_per_sec = 0;
+int HiNi=0;
+int NbB=0;
+//============================================
+
+int main() {
+ init();
+ //
+ CANMessage can_MsgRx;
+
+ while (1) {
+ if (can2.read(can_MsgRx)) {
+ led4=!led4;
+// check if new can message
+// if long response, ask for next part
+// check if frame is complete (case of multiframe)
+
+ if (can_MsgRx.id < 0x700) { // passive frame ,
+ msg_ReqFrameW--;
+
+ pc.printf("p\t%03X\t",can_MsgRx.id);
+ for (int i=0; i<can_MsgRx.len; i++) {
+ pc.printf(" ");
+ pc.printf("%02X",can_MsgRx.data[i]);
+ } // for
+ pc.printf("\r\n");
+
+ BT.printf("%03X",can_MsgRx.id);
+ Crc=can_MsgRx.id;
+ for (int i=0; i<can_MsgRx.len; i++) {
+ BT.printf("%02X",can_MsgRx.data[i]);
+ Crc = Crc + can_MsgRx.data[i];
+ } // for
+ BT.printf("%02X",Crc);
+ BT.printf("\r\n");
+
+ // calcs();
+
+ // send next req
+ if (msg_ReqFrameW <= 0) {
+ // it is ok to send another request
+ // because we received at least X passive frames since completion of previous request
+ // get the full message to send
+ for (int i=0; i<8; i++) {
+ msg_Request[i] = reqTable[msg_ReqIdx].code[i];
+ }
+ // log request
+ pc.printf("T\t%03X\t",reqTable[msg_ReqIdx].id);
+ for (int i=0; i<8; i++) {
+ pc.printf(" ");
+ pc.printf("%02X", msg_Request[i]);
+ } // for
+ pc.printf("\r\n");
+ // end log request
+ if (can2.write(CANMessage(reqTable[msg_ReqIdx].id, msg_Request,8))) {
+ send_per_sec++;
+ msg_ReqFrameW = 100;
+
+ // next req
+ do {
+ reqTable[msg_ReqIdx].fcnt++;
+ if (reqTable[msg_ReqIdx].fcnt >= reqTable[msg_ReqIdx].freq) {
+ reqTable[msg_ReqIdx].fcnt = 0;
+ } // endif
+ msg_ReqIdx++;
+ if (msg_ReqIdx > reqNumTbl) {
+ msg_ReqIdx = 0;
+ } // endif
+ } while (reqTable[msg_ReqIdx].fcnt != 0);
+ } // end if can2.write
+ } // end if (msg_ReqFrameW <= 0)
+
+ } else if (can_MsgRx.id >= 0x7E8 ) { // from here, we are dealing with answers
+ led2 =!led2;
+ HiNi = can_MsgRx.data[0]>>4; // test HighNibble to detect continuation frame
+ switch (HiNi) {
+ case 0: // short response if (can_MsgRx.data[0] < 0x10) {
+
+ BT.printf("%03X",can_MsgRx.id);
+ Crc=can_MsgRx.id;
+ for (int i=0; i<can_MsgRx.len; i++) {
+ BT.printf("%02X",can_MsgRx.data[i]);
+ Crc = Crc + can_MsgRx.data[i];
+ } // for
+ BT.printf("%02X",Crc);
+ BT.printf("\r\n");
+
+ pc.printf("r\t%03X\t",can_MsgRx.id);
+
+ for (int i=0; i<8; i++) {
+ pc.printf(" ");
+ pc.printf("%02X",can_MsgRx.data[i]);
+ } // for
+ pc.printf("\r\n");
+
+ msg_ReqFrameW = 2;
+ break;
+
+ case 1 : // long response if (can_MsgRx.data[0] == 0x10) {
+
+
+ NbB =int(can_MsgRx.data[1]); // the Number of Bytes in the multiframe
+ msg_ReqFrameW = 50; // continue receive
+ // store msg
+ msg_MF_Idx = 0;
+ // store id
+ msg_MF_Id = can_MsgRx.id;
+ // store from 1 to 7
+
+ for (int i = 1; i < can_MsgRx.len ; i++) {
+ msg_MF_data[msg_MF_Idx] = can_MsgRx.data[i];
+ msg_MF_Idx ++;
+ }
+
+ // send contination request
+ if (can2.write(CANMessage(can_MsgRx.id -8, msg_Continue, 8))) {
+ led3 =!led3;
+ }
+ break;
+
+ case 2 : // if (can_MsgRx.data[0] > 0x20 && can_MsgRx.data[0] <= 0x2F)
+ //
+ // store from 1 to 7
+ for (int i = 1; i < can_MsgRx.len ; i++) {
+ msg_MF_data[msg_MF_Idx] = can_MsgRx.data[i];
+ msg_MF_Idx ++;
+ }
+ //
+ if ( msg_MF_Idx > NbB) { // we received the full multiframe
+ msg_ReqFrameW = 2;
+ // multiframe is finished, we send the complete thing to pc
+
+ BT.printf("%03X",msg_MF_Id);
+ Crc=msg_MF_Id;
+ for (int i=0; i <= NbB; i++) {
+ BT.printf("%02X", msg_MF_data[i]);
+ Crc = Crc + msg_MF_data[i];
+ } // for
+ BT.printf("%02X",Crc);
+ BT.printf("\r\n");
+
+ pc.printf("r\t%03X\t",msg_MF_Id);
+ for (int i=0; i <= NbB; i++) {
+ pc.printf(" ");
+ pc.printf("%02X", msg_MF_data[i]);
+ } // for
+ pc.printf("\r\n");
+ // calcm();
+ } else {
+ msg_ReqFrameW = 50;
+ break;
+ default: // } else if (can_MsgRx.data[0] == 0x30) {
+ // ignore
+ break;
+ } // end if ( msg_MF_Idx >= NbB)
+ } // end switch (HiNi)
+
+
+ // Error check
+ int rerr = can2.rderror();
+ int werr = can2.tderror();
+ if (rerr > 0 || werr > 0) {
+ can2.reset();
+ led4 = !led4;
+ } // end if error
+ } // end if (can_MsgRx.id
+ } // end if (can2.read(can_MsgRx)
+ } // while (1)
+}
+
+//============================================
+// timchk()
+// description: this routine is called every 100microsec
+// a) manage time_counters
+
+//============================================
+void timchk() {
+
+ // count time
+ curr_us = timer.read_us(); // 0x00000000-0xFFFFFFFF looped
+ diff_us = curr_us - prev_us;
+ if (curr_us < prev_us) {
+ curr_uH++;
+ }
+ left_ms += diff_us;
+ while (left_ms >= 1000) { // timer.read_ms() not looped. it calculated from read_us() / 1000. so buggy.
+ curr_ms++;
+ ms_60000++;
+ ms_1000++;
+ if (ms_60000 >= 60000) {
+ ms_60000 = 0;
+ }
+ if (ms_1000 >= 1000) {
+ ms_1000 = 0;
+ curr_sc++;
+ send_per_sec =0;
+ rec_per_sec=0;
+
+ }
+ led1 = (ms_60000 / 250) & 1;
+ left_ms -= 1000;
+ //
+
+ }
+ if (diff_us > max_diff) {
+ max_diff = diff_us;
+ }
+ prev_us = curr_us;
+
+
+}
+
+
+
+//*----------------------------------------------------------------------------
+// init()
+// description: no comment
+//*----------------------------------------------------------------------------
+void init() {
+
+
+ // Init
+ can2.frequency(500000);
+ //can2->Attach(*can2rcv); // not ready now for queuing
+ pc.baud(921600);
+
+ BT.baud(38400); // when the BT module is new, the bps is 38400
+ BT.printf(" \r\n+STBD=460800\r\n"); // Set baudrate 460800. Save and Rest
+ wait(0.5);
+ BT.baud(115200); // in case we played before with 115200
+ BT.printf(" \r\n+STBD=460800\r\n"); // Set baudrate 460800. Save and Rest
+ wait(0.5);
+ BT.baud(460800);
+ wait(0.5);
+ BT.printf("\r\n+INQ=1\r\n"); // start broadcasting (make device visible)
+
+ // install filters ( Filter)
+ install_filters();
+
+ int reqtblresult = read_reqTable(reqTable, reqNumTbl);
+
+ timer.start();
+
+ led1=0;
+ led2=0;
+ led3=0;
+ led4=0;
+
+ msg_ReqFrameW = 2;
+ // CAN
+ prev_us = timer.read_us();
+ ticker.attach_us(&timchk, 100);
+}
+// When a CAN message is received, it is placed in queue
+void can2rcv() {
+ CANMessage msg;
+ if (can2.read(msg)) {
+// inQueue.Enqueue(msg);
+ led3=!led3;
+ }
+}
+
+/*============================================
+// calcs()
+// description: this routine is called at the recept of each single frame answer
+// we will use msg.id & msg.data[]
+//
+//
+//
+//============================================
+void calcs() {
+ if (msg.id== 0x00B4) { }
+ if (msg.id== 0x01C4) { }
+ if (msg.id== 0x0245) { }
+ if (msg.id== 0x03D3) { }
+ if (msg.id== 0x0498) { }
+ if (msg.id== 0x04A6) { }
+ if (msg.id== 0x07E8 && msg.data[1]==0x61 && msg.data[2]==0x3C) {}
+ if (msg.id== 0x07E8 && msg.data[1]==0x61 && msg.data[2]==0x49) {}
+ if (msg.id== 0x07E8 && msg.data[1]==0x41 && msg.data[2]==0x3C) {}
+ if (msg.id== 0x07E8 && msg.data[1]==0x41 && msg.data[2]==0x3E) {}
+
+ if (msg.id== 0x07EA && msg.data[1]==0x61) {
+ if (msg.data[2] == 0x61) {}
+ if (msg.data[2] == 0x62) {}
+ if (msg.data[2] == 0x67) {}
+ if (msg.data[2] == 0x68) {}
+ if (msg.data[2] == 0x70) {}
+ if (msg.data[2] == 0x71) {}
+ if (msg.data[2] == 0x87) {}
+ if (msg.data[2] == 0x8A) {}
+ if (msg.data[2] == 0x98) {}
+ }
+
+}
+
+
+//============================================
+// calcm()
+// description: this routine is called at the end of multiframe answer
+// we will use msg_MF_Id & msg_MF_data[]
+//
+//
+//
+//============================================
+void calcm() {
+ if ( msg_MF_Id== 0x07E8 && msg_MF_data[1]==0x61 && msg_MF_data[2]==0x01) {}
+ if ( msg_MF_Id== 0x07E8 && msg_MF_data[1]==0x61 && msg_MF_data[2]==0x49) {}
+ if ( msg_MF_Id== 0x07EA && msg_MF_data[1]==0x61 && msg_MF_data[2]==0x01) {}
+ if ( msg_MF_Id== 0x07E8 && msg_MF_data[1]==0x61 && msg_MF_data[2]==0x01) {}
+
+}
+*/
+
+/*----------------------------------------------------------------------------
+ CAN_wrFilter()
+ description: setup acceptance filter. CAN controller (1..2)
+
+ setup acceptance filter for CAN controller 2
+ original http://www.dragonwake.com/download/LPC1768/Example/CAN/CAN.c
+ simplified for CAN2 interface and std id (11 bit) only by YM1784
+ *----------------------------------------------------------------------------*/
+void CAN2_wrFilter (uint32_t id) {
+ static int CAN_std_cnt = 0;
+ uint32_t buf0, buf1;
+ int cnt1, cnt2, bound1;
+
+ /* Acceptance Filter Memory full */
+ if (((CAN_std_cnt + 1) >> 1) >= 512)
+ return; /* error: objects full */
+
+ /* Setup Acceptance Filter Configuration
+ Acceptance Filter Mode Register = Off */
+ LPC_CANAF->AFMR = 0x00000001;
+
+ id |= 1 << 13; /* Add controller number(2) */
+ id &= 0x0000F7FF; /* Mask out 16-bits of ID */
+
+ if (CAN_std_cnt == 0) { /* For entering first ID */
+ LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
+ } else if (CAN_std_cnt == 1) { /* For entering second ID */
+ if ((LPC_CANAF_RAM->mask[0] >> 16) > id)
+ LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
+ else
+ LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
+ } else {
+ /* Find where to insert new ID */
+ cnt1 = 0;
+ cnt2 = CAN_std_cnt;
+ bound1 = (CAN_std_cnt - 1) >> 1;
+ while (cnt1 <= bound1) { /* Loop through standard existing IDs */
+ if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id) {
+ cnt2 = cnt1 * 2;
+ break;
+ }
+ if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id) {
+ cnt2 = cnt1 * 2 + 1;
+ break;
+ }
+ cnt1++; /* cnt1 = U32 where to insert new ID */
+ } /* cnt2 = U16 where to insert new ID */
+
+ if (cnt1 > bound1) { /* Adding ID as last entry */
+ if ((CAN_std_cnt & 0x0001) == 0) /* Even number of IDs exists */
+ LPC_CANAF_RAM->mask[cnt1] = 0x0000FFFF | (id << 16);
+ else /* Odd number of IDs exists */
+ LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
+ } else {
+ buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
+ if ((cnt2 & 0x0001) == 0) /* Insert new mask to even address */
+ buf1 = (id << 16) | (buf0 >> 16);
+ else /* Insert new mask to odd address */
+ buf1 = (buf0 & 0xFFFF0000) | id;
+
+ LPC_CANAF_RAM->mask[cnt1] = buf1; /* Insert mask */
+
+ bound1 = CAN_std_cnt >> 1;
+ /* Move all remaining standard mask entries one place up */
+ while (cnt1 < bound1) {
+ cnt1++;
+ buf1 = LPC_CANAF_RAM->mask[cnt1];
+ LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
+ buf0 = buf1;
+ }
+
+ if ((CAN_std_cnt & 0x0001) == 0) /* Even number of IDs exists */
+ LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | (0x0000FFFF);
+ }
+ }
+ CAN_std_cnt++;
+
+ /* Calculate std ID start address (buf0) and ext ID start address <- none (buf1) */
+ buf0 = ((CAN_std_cnt + 1) >> 1) << 2;
+ buf1 = buf0;
+
+ /* Setup acceptance filter pointers */
+ LPC_CANAF->SFF_sa = 0;
+ LPC_CANAF->SFF_GRP_sa = buf0;
+ LPC_CANAF->EFF_sa = buf0;
+ LPC_CANAF->EFF_GRP_sa = buf1;
+ LPC_CANAF->ENDofTable = buf1;
+
+ LPC_CANAF->AFMR = 0x00000000; /* Use acceptance filter */
+} // CAN2_wrFilter
+
+
+/* =================================================
+read /local/filters.txt & install them
+the file contains something like:
+// max line length 128
+025 // comments can be added to note what this filter (025) is for
+030
+038
+039
+// 03A // comment out this line so this filter (03A) will not be installed
+230
+244
+
+ Author: teamprii
+=====================================================*/
+int install_filters() {
+ const int maxlinelen=128; // max line length in filters.txt file; 128 should be plenty for things like "0B4 // comment for 0B4 ....... " etc.
+ char str[maxlinelen];
+ int filter;
+ ifstream infile("/local/filters.txt"); // hard coded pathname for filter specification file
+ if (infile.is_open()) {
+ while (infile.good()) {
+ infile.getline(str,maxlinelen);
+ if (str[0]=='/' && str[1]=='/') {
+ // pc.printf("skip commented line %s",str);
+ // pc.printf("\r\n");
+ // cout<<str<<", skip commented line."<<endl; // skip commented line
+ } else {
+ sscanf(str,"%x",&filter);
+ // cout<<str<<", install filter "<<hex<<filter<<endl; // to be replaced with CAN2_wrFilter(hex);
+ pc.printf("filter:\t%03X\r\n",filter);
+ CAN2_wrFilter (filter);
+ }
+ }
+ infile.close();
+ return 0;
+ } else {
+ // pc.printf("Unable to open filter spec file");
+ // cout<<"Unable to open filter spec file";
+ return -1;
+ }
+}
+int read_reqTable(vector<reqTbl>& reqtable, int& reqnumtbl) {
+ const int maxlinelen=256; // max line length in request.txt file; 256 should be plenty.
+ char str[maxlinelen];
+ int id; // PID
+ int freq; // request frequency
+ int codej; // to store read code temporarily
+ reqTbl tmp;
+ ifstream infile("/local/request.txt"); // hard coded pathname for request specification file
+ if (infile.is_open()) {
+ while (infile.good()) {
+ infile.getline(str,maxlinelen);
+ if (str[0]=='/' && str[1]=='/') {
+ // pc.printf("skip commented line %s",str);
+ // pc.printf("\r\n");
+ // cout<<str<<", skip commented line."<<endl; // skip commented line
+ } else {
+ // cout<<str<<", add this request to reqTable."<<endl; // add request to reqTable
+ stringstream ss;
+ ss<<str;
+ if (ss.str().length() > 10) { // use only real lines
+ ss>>hex>>id>>freq;
+ pc.printf("\r\n add this request to reqTable.\r\n");
+ tmp.id=id;
+ tmp.freq=freq;
+ vector<int> code; // list of code
+ do {
+ ss>>hex>>codej;
+ if (ss.good()) {
+ code.push_back(codej);
+ }
+ } while (ss.good());
+ tmp.code=code;
+ //cout<<"PID="<<tmp.id<<", freq="<<tmp.freq<<", code=";
+ pc.printf("PID=%03X",tmp.id);
+ pc.printf("\tfreq=%03d",tmp.freq);
+ pc.printf("\tCode=");
+
+ for (int j=0; j<(int)tmp.code.size(); j++) {
+ pc.printf(" %02x",tmp.code[j]);
+ // cout<<" "<<tmp.code[j]<<", ";
+ }
+ // cout<<endl;
+ pc.printf("\r\n");
+ reqtable.push_back(tmp);
+ }
+ }
+ }
+ reqnumtbl=reqtable.size();
+ infile.close();
+ return 0;
+ } else {
+ // pc.printf("Unable to open request spec file");
+ // cout<<"Unable to open request spec file";
+ return -2;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Apr 09 15:27:55 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479