yotaro morizumi / Mbed 2 deprecated zoomy_customLibrary

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers scrp_slave.cpp Source File

scrp_slave.cpp

00001 #include "scrp_slave.hpp"
00002 
00003 #define STX 0x41
00004 #define DMY 0xff
00005 
00006 ScrpSlave::ScrpSlave(PinName TX1,PinName RX1,uint32_t addr,bool interrupt)
00007     :port1(TX1,RX1,115200),port2(port1),address_(addr),interrupt_(interrupt){
00008     mode_ = 0;
00009     init();
00010 }
00011 
00012 ScrpSlave::ScrpSlave(PinName TX1,PinName RX1,PinName REDE1,uint32_t addr,bool interrupt)
00013     :port1(TX1,RX1,115200),port2(port1),address_(addr),interrupt_(interrupt){
00014     mode_ = 1;
00015     rede_ = new DigitalOut(REDE1,0);
00016     init();
00017 }
00018 
00019 ScrpSlave::ScrpSlave(PinName TX1,PinName RX1,PinName TX2,PinName RX2,uint32_t addr,bool interrupt)
00020     :port1(TX1,RX1,115200),port2(TX2,RX2,115200),address_(addr),interrupt_(interrupt){
00021     mode_ = 2;
00022     serial_[1] = &port2;
00023     if(interrupt_){
00024         serial_[1]->attach(callback(this,&ScrpSlave::receive1),Serial::RxIrq);
00025     }
00026     init();
00027 }
00028 
00029 ScrpSlave::ScrpSlave(PinName TX1,PinName RX1,PinName REDE1,PinName TX2,PinName RX2,uint32_t addr,bool interrupt)
00030     :port1(TX1,RX1,115200),port2(TX2,RX2,115200),address_(addr),interrupt_(interrupt){
00031     mode_ = 3;
00032     rede_ = new DigitalOut(REDE1,0);
00033     serial_[1] = &port2;
00034     if(interrupt_){
00035         serial_[1]->attach(callback(this,&ScrpSlave::receive1),Serial::RxIrq);
00036     }
00037     init();
00038 }
00039 
00040 void ScrpSlave::init(){
00041     for(int i = 0;i<2;i++){
00042         wait_data_[i] = false;
00043         stx_flag_[i] = false;
00044         id_ok_[i] = false;
00045         get_response_[i] = false;
00046     }
00047     for(int i = 1;i<256;++i){
00048         procs_[i] = NULL;
00049     }
00050     responseFunc_ = NULL;
00051     all_receive_ = false;
00052     serial_[0] = &port1;
00053     if(interrupt_){
00054         serial_[0]->attach(callback(this,&ScrpSlave::receive0),Serial::RxIrq);
00055     }
00056     if(address_ < 256){
00057         my_id_ = address_;//引数addressが0~254の時その値をidとして使用
00058         all_receive_ = (address_ == 255);//引数addressが255の時すべてのidに応答する、全受信モードになる
00059         return;
00060     }
00061     //フラッシュメモリーのアクセスにエラーが出たら、アドレスは10に設定される。
00062     flash_ = new FlashIAP;
00063     if(flash_->init()==0){
00064         if(flash_->read(&my_id_,address_,1) != 0){
00065             send2(222,222,222);
00066             my_id_ = 10;
00067         }
00068     }else{
00069         send2(111,111,111);
00070         my_id_ = 10;
00071     }
00072 }
00073 
00074 void ScrpSlave::receive(){
00075     if(interrupt_){
00076         return;
00077     }
00078     while(port1.readable()){
00079         check(0);
00080     }
00081     if(mode_ > 1){
00082         while(port2.readable()){
00083             check(1);
00084         }
00085     }
00086 }
00087 
00088 void ScrpSlave::receive0(){
00089     check(0);
00090 }
00091 
00092 void ScrpSlave::receive1(){
00093     check(1);
00094 }
00095 
00096 void ScrpSlave::attachResponse(void (*func)(uint8_t id, uint8_t cmd, int16_t response)){
00097     responseFunc_ = func;
00098 }
00099 
00100 void ScrpSlave::addCMD(uint8_t cmd, bool (*proc)(int rx_data, int& tx_data)){
00101     if(cmd == 0 || cmd == 254 || cmd == 253)return;
00102     procs_[cmd] = proc;
00103 }
00104 
00105 void ScrpSlave::changeID(uint8_t id){
00106     if(address_ < 256){
00107         return;
00108     }
00109     flash_->erase(address_,flash_->get_sector_size(address_));
00110     flash_->program(&id,address_,1);
00111 }
00112 
00113 bool ScrpSlave::send1(uint8_t id,uint8_t cmd,int16_t tx_data, bool flag){
00114     return sending(0,id,cmd,tx_data,flag);
00115 }
00116 
00117 bool ScrpSlave::send2(uint8_t id,uint8_t cmd,int16_t tx_data, bool flag){
00118     return sending((mode_ > 1),id,cmd,tx_data,flag);
00119 }
00120 
00121 bool ScrpSlave::sending(int port,uint8_t id,uint8_t cmd,int16_t tx_data,bool flag){
00122     if(!serial_[port]->writeable()){
00123         return false;
00124     }
00125     if(flag){
00126         wait_data_[port] = true;//データ返信待ち
00127         get_response_[port] = false;
00128     }
00129     uint8_t tx_dataL = tx_data;
00130     uint8_t tx_dataH = tx_data >> 8;
00131     uint8_t tx_sum = id + cmd + tx_dataL + tx_dataH;
00132 
00133     const uint8_t data[8] = {DMY, STX, id, cmd, tx_dataL, tx_dataH, tx_sum, DMY};
00134     memcpy(send_data_[port],data,8);
00135     if(interrupt_){
00136         prime(port);
00137     }else{
00138         sendNoInterrupt(port);
00139     }
00140     return true;
00141 }
00142 
00143 void ScrpSlave::sendNoInterrupt(uint8_t port){
00144     if(mode_%2 == 1 && port == 0){
00145         rede_->write(1);
00146     }
00147     for(int i = 0;i < 8;i++){
00148         serial_[port]->putc(send_data_[port][i]);
00149         while(!serial_[port]->writeable());
00150     }
00151     if(mode_%2 == 1 && port == 0){
00152         rede_->write(0);
00153     }
00154 }
00155 
00156 bool ScrpSlave::getResponse(uint8_t port){
00157     if(port > 1 || (port == 1 && mode_ < 2)){
00158         return false;
00159     }
00160     return get_response_[port];
00161 }
00162 
00163 bool ScrpSlave::isWaiting(uint8_t port){
00164     if(port > 1 || (port == 1 && mode_ < 2)){
00165         return false;
00166     }
00167     return wait_data_[port];
00168 }
00169 
00170 int16_t ScrpSlave::receiveData(uint8_t port){
00171     //ポート指定が正しいかどうか。
00172     if(port > 1 || (port == 1 && mode_ < 2)){
00173         return -1;
00174     }
00175     //データがあるか確認。
00176     if(get_response_[port]){
00177         return rx_data_[port];
00178     }else{
00179         return -1;
00180     }
00181 }
00182 
00183 uint8_t ScrpSlave::receiveCmd(){
00184     return rx_cmd_;//受信したcmd番号を返す。
00185 }
00186 
00187 uint8_t ScrpSlave::receiveId(){
00188     return rx_id_;//受信したidを返す。
00189 }
00190 
00191 uint8_t ScrpSlave::receivePort(){
00192     return receive_port_;//直近で受信したポートを返す。
00193 }
00194 
00195 void ScrpSlave::check(int port){
00196     if(id_ok_[port]){
00197         tmp_data_[port][data_count_[port]] = serial_[port]->getc();
00198         data_count_[port]++;
00199         if(data_count_[port] > 4){
00200             stx_flag_[port] = false;//通信フラグクリア
00201             id_ok_[port] = false;
00202             
00203             uint8_t sum = 0;
00204             for(int i = 0;i<4;i++){
00205                 sum += tmp_data_[port][i];
00206             }
00207             if(sum != tmp_data_[port][4]){//check sum照合
00208                 return;
00209             }
00210             receive_port_ = port;//受信したポート番号を保存
00211             uint8_t rx_id = tmp_data_[port][0];
00212             uint8_t rx_cmd = tmp_data_[port][1];
00213             rx_data_[port] = (int16_t)(tmp_data_[port][2] + ((int16_t)tmp_data_[port][3] << 8));
00214             if(wait_data_[port]){//データ返信待ち時
00215                 wait_data_[port] = false;
00216                 get_response_[port] = true;
00217                 if(responseFunc_ != NULL){
00218                     responseFunc_(rx_id,rx_cmd,rx_data_[port]);
00219                 }
00220                 return;
00221             }else if(get_response_[port]){
00222                 get_response_[port] = false;
00223             }
00224             rx_cmd_ = rx_cmd;//メンバ変数に保存
00225             bool broadcast = (tmp_data_[port][0] == 255);
00226             
00227             int tx_data = rx_data_[port];
00228             if(rx_cmd == 0){//通信テスト
00229             }else if(rx_cmd == 254){//id変更
00230                 uint8_t new_id = rx_data_[port];
00231                 my_id_ = new_id;
00232                 changeID(new_id);
00233             }else if(rx_cmd == 253){//id確認
00234                 tx_data = my_id_;
00235                 rx_cmd = 250 + all_receive_*5;
00236                 broadcast = false;
00237             }else if(procs_[rx_cmd] == NULL || !procs_[rx_cmd](rx_data_[port],tx_data)){
00238                 return;
00239             }
00240             if(broadcast){
00241                 return;//全体送信の時はレスポンスを返さない。
00242             }
00243             uint8_t tx_dataL = tx_data;
00244             uint8_t tx_dataH = tx_data >> 8;
00245             uint8_t tx_sum = my_id_ + rx_cmd + tx_dataL + tx_dataH;
00246     
00247             const uint8_t data[8] = {DMY, STX, my_id_, rx_cmd, tx_dataL, tx_dataH, tx_sum, DMY};
00248             memcpy(send_data_[port],data,8);
00249             if(interrupt_){
00250                 prime(port);
00251             }else{
00252                 sendNoInterrupt(port);
00253             }
00254         }
00255     }else if(stx_flag_[port]){
00256         uint8_t get_data = serial_[port]->getc();
00257         if(get_data == my_id_ || get_data == 255 || (all_receive_ && !wait_data_[port])){
00258             id_ok_[port] = true;
00259             wait_data_[port] = false;
00260             tmp_data_[port][0] = get_data;
00261             data_count_[port]++;
00262         }else if(wait_data_[port]){
00263             id_ok_[port] = true;
00264             tmp_data_[port][0] = get_data;
00265             data_count_[port]++;
00266         }else{
00267             stx_flag_[port] = false;
00268         }
00269         rx_id_ = get_data;//メンバ変数に保存
00270     }else if(serial_[port]->getc() == STX){
00271         stx_flag_[port] = true;
00272         data_count_[port] = 0;
00273         id_ok_[port] = false;
00274         //id_ok_[port] = wait_data_[port];//データ返信待ち時はidチェック無し
00275     }
00276     return;
00277 }
00278 
00279 void ScrpSlave::dataSend0(){
00280     while(serial_[0]->writeable()){
00281         if(data_count_[0] < 8){
00282             serial_[0]->putc(send_data_[0][data_count_[0]++]);
00283         }else{
00284             serial_[0]->attach(NULL, Serial::TxIrq);
00285             if(mode_%2 == 1){
00286                 rede_->write(0);
00287             }
00288             break;
00289         }
00290     }
00291 }
00292 
00293 void ScrpSlave::dataSend1(){
00294     while(serial_[1]->writeable()){
00295         if(data_count_[1] < 8){
00296             serial_[1]->putc(send_data_[1][data_count_[1]++]);
00297         }else{
00298             serial_[1]->attach(NULL, Serial::TxIrq);
00299             break;
00300         }
00301     }
00302 }
00303 
00304 void ScrpSlave::prime(int port){
00305     serial_[port]->attach(NULL, Serial::TxIrq);
00306     data_count_[port] = 0;
00307     if(port == 0){
00308         if(mode_%2 == 1){
00309             rede_->write(1);
00310         }
00311         dataSend0();
00312         serial_[0]->attach(callback(this, &ScrpSlave::dataSend0), Serial::TxIrq);
00313     }else{
00314         dataSend1();
00315         serial_[1]->attach(callback(this, &ScrpSlave::dataSend1), Serial::TxIrq);
00316     }
00317 }
00318 
00319 ScrpSlave::~ScrpSlave(){
00320     delete flash_;
00321     if(mode_%2 == 1){
00322         delete rede_;
00323     }
00324 }