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.
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 }
Generated on Sat Oct 15 2022 07:52:33 by
1.7.2