my new gear...

Dependencies:   mbed

Committer:
yootee
Date:
Sat Oct 15 07:52:25 2022 +0000
Revision:
22:394337a4205a
Parent:
3:a9b4b2565a23
upgrade

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yootee 3:a9b4b2565a23 1 #include "scrp_slave.hpp"
yootee 3:a9b4b2565a23 2
yootee 3:a9b4b2565a23 3 #define STX 0x41
yootee 3:a9b4b2565a23 4 #define DMY 0xff
yootee 3:a9b4b2565a23 5
yootee 3:a9b4b2565a23 6 ScrpSlave::ScrpSlave(PinName TX1,PinName RX1,uint32_t addr,bool interrupt)
yootee 3:a9b4b2565a23 7 :port1(TX1,RX1,115200),port2(port1),address_(addr),interrupt_(interrupt){
yootee 3:a9b4b2565a23 8 mode_ = 0;
yootee 3:a9b4b2565a23 9 init();
yootee 3:a9b4b2565a23 10 }
yootee 3:a9b4b2565a23 11
yootee 3:a9b4b2565a23 12 ScrpSlave::ScrpSlave(PinName TX1,PinName RX1,PinName REDE1,uint32_t addr,bool interrupt)
yootee 3:a9b4b2565a23 13 :port1(TX1,RX1,115200),port2(port1),address_(addr),interrupt_(interrupt){
yootee 3:a9b4b2565a23 14 mode_ = 1;
yootee 3:a9b4b2565a23 15 rede_ = new DigitalOut(REDE1,0);
yootee 3:a9b4b2565a23 16 init();
yootee 3:a9b4b2565a23 17 }
yootee 3:a9b4b2565a23 18
yootee 3:a9b4b2565a23 19 ScrpSlave::ScrpSlave(PinName TX1,PinName RX1,PinName TX2,PinName RX2,uint32_t addr,bool interrupt)
yootee 3:a9b4b2565a23 20 :port1(TX1,RX1,115200),port2(TX2,RX2,115200),address_(addr),interrupt_(interrupt){
yootee 3:a9b4b2565a23 21 mode_ = 2;
yootee 3:a9b4b2565a23 22 serial_[1] = &port2;
yootee 3:a9b4b2565a23 23 if(interrupt_){
yootee 3:a9b4b2565a23 24 serial_[1]->attach(callback(this,&ScrpSlave::receive1),Serial::RxIrq);
yootee 3:a9b4b2565a23 25 }
yootee 3:a9b4b2565a23 26 init();
yootee 3:a9b4b2565a23 27 }
yootee 3:a9b4b2565a23 28
yootee 3:a9b4b2565a23 29 ScrpSlave::ScrpSlave(PinName TX1,PinName RX1,PinName REDE1,PinName TX2,PinName RX2,uint32_t addr,bool interrupt)
yootee 3:a9b4b2565a23 30 :port1(TX1,RX1,115200),port2(TX2,RX2,115200),address_(addr),interrupt_(interrupt){
yootee 3:a9b4b2565a23 31 mode_ = 3;
yootee 3:a9b4b2565a23 32 rede_ = new DigitalOut(REDE1,0);
yootee 3:a9b4b2565a23 33 serial_[1] = &port2;
yootee 3:a9b4b2565a23 34 if(interrupt_){
yootee 3:a9b4b2565a23 35 serial_[1]->attach(callback(this,&ScrpSlave::receive1),Serial::RxIrq);
yootee 3:a9b4b2565a23 36 }
yootee 3:a9b4b2565a23 37 init();
yootee 3:a9b4b2565a23 38 }
yootee 3:a9b4b2565a23 39
yootee 3:a9b4b2565a23 40 void ScrpSlave::init(){
yootee 3:a9b4b2565a23 41 for(int i = 0;i<2;i++){
yootee 3:a9b4b2565a23 42 wait_data_[i] = false;
yootee 3:a9b4b2565a23 43 stx_flag_[i] = false;
yootee 3:a9b4b2565a23 44 id_ok_[i] = false;
yootee 3:a9b4b2565a23 45 get_response_[i] = false;
yootee 3:a9b4b2565a23 46 }
yootee 3:a9b4b2565a23 47 for(int i = 1;i<256;++i){
yootee 3:a9b4b2565a23 48 procs_[i] = NULL;
yootee 3:a9b4b2565a23 49 }
yootee 3:a9b4b2565a23 50 responseFunc_ = NULL;
yootee 3:a9b4b2565a23 51 all_receive_ = false;
yootee 3:a9b4b2565a23 52 serial_[0] = &port1;
yootee 3:a9b4b2565a23 53 if(interrupt_){
yootee 3:a9b4b2565a23 54 serial_[0]->attach(callback(this,&ScrpSlave::receive0),Serial::RxIrq);
yootee 3:a9b4b2565a23 55 }
yootee 3:a9b4b2565a23 56 if(address_ < 256){
yootee 3:a9b4b2565a23 57 my_id_ = address_;//引数addressが0~254の時その値をidとして使用
yootee 3:a9b4b2565a23 58 all_receive_ = (address_ == 255);//引数addressが255の時すべてのidに応答する、全受信モードになる
yootee 3:a9b4b2565a23 59 return;
yootee 3:a9b4b2565a23 60 }
yootee 3:a9b4b2565a23 61 //フラッシュメモリーのアクセスにエラーが出たら、アドレスは10に設定される。
yootee 3:a9b4b2565a23 62 flash_ = new FlashIAP;
yootee 3:a9b4b2565a23 63 if(flash_->init()==0){
yootee 3:a9b4b2565a23 64 if(flash_->read(&my_id_,address_,1) != 0){
yootee 3:a9b4b2565a23 65 send2(222,222,222);
yootee 3:a9b4b2565a23 66 my_id_ = 10;
yootee 3:a9b4b2565a23 67 }
yootee 3:a9b4b2565a23 68 }else{
yootee 3:a9b4b2565a23 69 send2(111,111,111);
yootee 3:a9b4b2565a23 70 my_id_ = 10;
yootee 3:a9b4b2565a23 71 }
yootee 3:a9b4b2565a23 72 }
yootee 3:a9b4b2565a23 73
yootee 3:a9b4b2565a23 74 void ScrpSlave::receive(){
yootee 3:a9b4b2565a23 75 if(interrupt_){
yootee 3:a9b4b2565a23 76 return;
yootee 3:a9b4b2565a23 77 }
yootee 3:a9b4b2565a23 78 while(port1.readable()){
yootee 3:a9b4b2565a23 79 check(0);
yootee 3:a9b4b2565a23 80 }
yootee 3:a9b4b2565a23 81 if(mode_ > 1){
yootee 3:a9b4b2565a23 82 while(port2.readable()){
yootee 3:a9b4b2565a23 83 check(1);
yootee 3:a9b4b2565a23 84 }
yootee 3:a9b4b2565a23 85 }
yootee 3:a9b4b2565a23 86 }
yootee 3:a9b4b2565a23 87
yootee 3:a9b4b2565a23 88 void ScrpSlave::receive0(){
yootee 3:a9b4b2565a23 89 check(0);
yootee 3:a9b4b2565a23 90 }
yootee 3:a9b4b2565a23 91
yootee 3:a9b4b2565a23 92 void ScrpSlave::receive1(){
yootee 3:a9b4b2565a23 93 check(1);
yootee 3:a9b4b2565a23 94 }
yootee 3:a9b4b2565a23 95
yootee 3:a9b4b2565a23 96 void ScrpSlave::attachResponse(void (*func)(uint8_t id, uint8_t cmd, int16_t response)){
yootee 3:a9b4b2565a23 97 responseFunc_ = func;
yootee 3:a9b4b2565a23 98 }
yootee 3:a9b4b2565a23 99
yootee 3:a9b4b2565a23 100 void ScrpSlave::addCMD(uint8_t cmd, bool (*proc)(int rx_data, int& tx_data)){
yootee 3:a9b4b2565a23 101 if(cmd == 0 || cmd == 254 || cmd == 253)return;
yootee 3:a9b4b2565a23 102 procs_[cmd] = proc;
yootee 3:a9b4b2565a23 103 }
yootee 3:a9b4b2565a23 104
yootee 3:a9b4b2565a23 105 void ScrpSlave::changeID(uint8_t id){
yootee 3:a9b4b2565a23 106 if(address_ < 256){
yootee 3:a9b4b2565a23 107 return;
yootee 3:a9b4b2565a23 108 }
yootee 3:a9b4b2565a23 109 flash_->erase(address_,flash_->get_sector_size(address_));
yootee 3:a9b4b2565a23 110 flash_->program(&id,address_,1);
yootee 3:a9b4b2565a23 111 }
yootee 3:a9b4b2565a23 112
yootee 3:a9b4b2565a23 113 bool ScrpSlave::send1(uint8_t id,uint8_t cmd,int16_t tx_data, bool flag){
yootee 3:a9b4b2565a23 114 return sending(0,id,cmd,tx_data,flag);
yootee 3:a9b4b2565a23 115 }
yootee 3:a9b4b2565a23 116
yootee 3:a9b4b2565a23 117 bool ScrpSlave::send2(uint8_t id,uint8_t cmd,int16_t tx_data, bool flag){
yootee 3:a9b4b2565a23 118 return sending((mode_ > 1),id,cmd,tx_data,flag);
yootee 3:a9b4b2565a23 119 }
yootee 3:a9b4b2565a23 120
yootee 3:a9b4b2565a23 121 bool ScrpSlave::sending(int port,uint8_t id,uint8_t cmd,int16_t tx_data,bool flag){
yootee 3:a9b4b2565a23 122 if(!serial_[port]->writeable()){
yootee 3:a9b4b2565a23 123 return false;
yootee 3:a9b4b2565a23 124 }
yootee 3:a9b4b2565a23 125 if(flag){
yootee 3:a9b4b2565a23 126 wait_data_[port] = true;//データ返信待ち
yootee 3:a9b4b2565a23 127 get_response_[port] = false;
yootee 3:a9b4b2565a23 128 }
yootee 3:a9b4b2565a23 129 uint8_t tx_dataL = tx_data;
yootee 3:a9b4b2565a23 130 uint8_t tx_dataH = tx_data >> 8;
yootee 3:a9b4b2565a23 131 uint8_t tx_sum = id + cmd + tx_dataL + tx_dataH;
yootee 3:a9b4b2565a23 132
yootee 3:a9b4b2565a23 133 const uint8_t data[8] = {DMY, STX, id, cmd, tx_dataL, tx_dataH, tx_sum, DMY};
yootee 3:a9b4b2565a23 134 memcpy(send_data_[port],data,8);
yootee 3:a9b4b2565a23 135 if(interrupt_){
yootee 3:a9b4b2565a23 136 prime(port);
yootee 3:a9b4b2565a23 137 }else{
yootee 3:a9b4b2565a23 138 sendNoInterrupt(port);
yootee 3:a9b4b2565a23 139 }
yootee 3:a9b4b2565a23 140 return true;
yootee 3:a9b4b2565a23 141 }
yootee 3:a9b4b2565a23 142
yootee 3:a9b4b2565a23 143 void ScrpSlave::sendNoInterrupt(uint8_t port){
yootee 3:a9b4b2565a23 144 if(mode_%2 == 1 && port == 0){
yootee 3:a9b4b2565a23 145 rede_->write(1);
yootee 3:a9b4b2565a23 146 }
yootee 3:a9b4b2565a23 147 for(int i = 0;i < 8;i++){
yootee 3:a9b4b2565a23 148 serial_[port]->putc(send_data_[port][i]);
yootee 3:a9b4b2565a23 149 while(!serial_[port]->writeable());
yootee 3:a9b4b2565a23 150 }
yootee 3:a9b4b2565a23 151 if(mode_%2 == 1 && port == 0){
yootee 3:a9b4b2565a23 152 rede_->write(0);
yootee 3:a9b4b2565a23 153 }
yootee 3:a9b4b2565a23 154 }
yootee 3:a9b4b2565a23 155
yootee 3:a9b4b2565a23 156 bool ScrpSlave::getResponse(uint8_t port){
yootee 3:a9b4b2565a23 157 if(port > 1 || (port == 1 && mode_ < 2)){
yootee 3:a9b4b2565a23 158 return false;
yootee 3:a9b4b2565a23 159 }
yootee 3:a9b4b2565a23 160 return get_response_[port];
yootee 3:a9b4b2565a23 161 }
yootee 3:a9b4b2565a23 162
yootee 3:a9b4b2565a23 163 bool ScrpSlave::isWaiting(uint8_t port){
yootee 3:a9b4b2565a23 164 if(port > 1 || (port == 1 && mode_ < 2)){
yootee 3:a9b4b2565a23 165 return false;
yootee 3:a9b4b2565a23 166 }
yootee 3:a9b4b2565a23 167 return wait_data_[port];
yootee 3:a9b4b2565a23 168 }
yootee 3:a9b4b2565a23 169
yootee 3:a9b4b2565a23 170 int16_t ScrpSlave::receiveData(uint8_t port){
yootee 3:a9b4b2565a23 171 //ポート指定が正しいかどうか。
yootee 3:a9b4b2565a23 172 if(port > 1 || (port == 1 && mode_ < 2)){
yootee 3:a9b4b2565a23 173 return -1;
yootee 3:a9b4b2565a23 174 }
yootee 3:a9b4b2565a23 175 //データがあるか確認。
yootee 3:a9b4b2565a23 176 if(get_response_[port]){
yootee 3:a9b4b2565a23 177 return rx_data_[port];
yootee 3:a9b4b2565a23 178 }else{
yootee 3:a9b4b2565a23 179 return -1;
yootee 3:a9b4b2565a23 180 }
yootee 3:a9b4b2565a23 181 }
yootee 3:a9b4b2565a23 182
yootee 3:a9b4b2565a23 183 uint8_t ScrpSlave::receiveCmd(){
yootee 3:a9b4b2565a23 184 return rx_cmd_;//受信したcmd番号を返す。
yootee 3:a9b4b2565a23 185 }
yootee 3:a9b4b2565a23 186
yootee 3:a9b4b2565a23 187 uint8_t ScrpSlave::receiveId(){
yootee 3:a9b4b2565a23 188 return rx_id_;//受信したidを返す。
yootee 3:a9b4b2565a23 189 }
yootee 3:a9b4b2565a23 190
yootee 3:a9b4b2565a23 191 uint8_t ScrpSlave::receivePort(){
yootee 3:a9b4b2565a23 192 return receive_port_;//直近で受信したポートを返す。
yootee 3:a9b4b2565a23 193 }
yootee 3:a9b4b2565a23 194
yootee 3:a9b4b2565a23 195 void ScrpSlave::check(int port){
yootee 3:a9b4b2565a23 196 if(id_ok_[port]){
yootee 3:a9b4b2565a23 197 tmp_data_[port][data_count_[port]] = serial_[port]->getc();
yootee 3:a9b4b2565a23 198 data_count_[port]++;
yootee 3:a9b4b2565a23 199 if(data_count_[port] > 4){
yootee 3:a9b4b2565a23 200 stx_flag_[port] = false;//通信フラグクリア
yootee 3:a9b4b2565a23 201 id_ok_[port] = false;
yootee 3:a9b4b2565a23 202
yootee 3:a9b4b2565a23 203 uint8_t sum = 0;
yootee 3:a9b4b2565a23 204 for(int i = 0;i<4;i++){
yootee 3:a9b4b2565a23 205 sum += tmp_data_[port][i];
yootee 3:a9b4b2565a23 206 }
yootee 3:a9b4b2565a23 207 if(sum != tmp_data_[port][4]){//check sum照合
yootee 3:a9b4b2565a23 208 return;
yootee 3:a9b4b2565a23 209 }
yootee 3:a9b4b2565a23 210 receive_port_ = port;//受信したポート番号を保存
yootee 3:a9b4b2565a23 211 uint8_t rx_id = tmp_data_[port][0];
yootee 3:a9b4b2565a23 212 uint8_t rx_cmd = tmp_data_[port][1];
yootee 3:a9b4b2565a23 213 rx_data_[port] = (int16_t)(tmp_data_[port][2] + ((int16_t)tmp_data_[port][3] << 8));
yootee 3:a9b4b2565a23 214 if(wait_data_[port]){//データ返信待ち時
yootee 3:a9b4b2565a23 215 wait_data_[port] = false;
yootee 3:a9b4b2565a23 216 get_response_[port] = true;
yootee 3:a9b4b2565a23 217 if(responseFunc_ != NULL){
yootee 3:a9b4b2565a23 218 responseFunc_(rx_id,rx_cmd,rx_data_[port]);
yootee 3:a9b4b2565a23 219 }
yootee 3:a9b4b2565a23 220 return;
yootee 3:a9b4b2565a23 221 }else if(get_response_[port]){
yootee 3:a9b4b2565a23 222 get_response_[port] = false;
yootee 3:a9b4b2565a23 223 }
yootee 3:a9b4b2565a23 224 rx_cmd_ = rx_cmd;//メンバ変数に保存
yootee 3:a9b4b2565a23 225 bool broadcast = (tmp_data_[port][0] == 255);
yootee 3:a9b4b2565a23 226
yootee 3:a9b4b2565a23 227 int tx_data = rx_data_[port];
yootee 3:a9b4b2565a23 228 if(rx_cmd == 0){//通信テスト
yootee 3:a9b4b2565a23 229 }else if(rx_cmd == 254){//id変更
yootee 3:a9b4b2565a23 230 uint8_t new_id = rx_data_[port];
yootee 3:a9b4b2565a23 231 my_id_ = new_id;
yootee 3:a9b4b2565a23 232 changeID(new_id);
yootee 3:a9b4b2565a23 233 }else if(rx_cmd == 253){//id確認
yootee 3:a9b4b2565a23 234 tx_data = my_id_;
yootee 3:a9b4b2565a23 235 rx_cmd = 250 + all_receive_*5;
yootee 3:a9b4b2565a23 236 broadcast = false;
yootee 3:a9b4b2565a23 237 }else if(procs_[rx_cmd] == NULL || !procs_[rx_cmd](rx_data_[port],tx_data)){
yootee 3:a9b4b2565a23 238 return;
yootee 3:a9b4b2565a23 239 }
yootee 3:a9b4b2565a23 240 if(broadcast){
yootee 3:a9b4b2565a23 241 return;//全体送信の時はレスポンスを返さない。
yootee 3:a9b4b2565a23 242 }
yootee 3:a9b4b2565a23 243 uint8_t tx_dataL = tx_data;
yootee 3:a9b4b2565a23 244 uint8_t tx_dataH = tx_data >> 8;
yootee 3:a9b4b2565a23 245 uint8_t tx_sum = my_id_ + rx_cmd + tx_dataL + tx_dataH;
yootee 3:a9b4b2565a23 246
yootee 3:a9b4b2565a23 247 const uint8_t data[8] = {DMY, STX, my_id_, rx_cmd, tx_dataL, tx_dataH, tx_sum, DMY};
yootee 3:a9b4b2565a23 248 memcpy(send_data_[port],data,8);
yootee 3:a9b4b2565a23 249 if(interrupt_){
yootee 3:a9b4b2565a23 250 prime(port);
yootee 3:a9b4b2565a23 251 }else{
yootee 3:a9b4b2565a23 252 sendNoInterrupt(port);
yootee 3:a9b4b2565a23 253 }
yootee 3:a9b4b2565a23 254 }
yootee 3:a9b4b2565a23 255 }else if(stx_flag_[port]){
yootee 3:a9b4b2565a23 256 uint8_t get_data = serial_[port]->getc();
yootee 3:a9b4b2565a23 257 if(get_data == my_id_ || get_data == 255 || (all_receive_ && !wait_data_[port])){
yootee 3:a9b4b2565a23 258 id_ok_[port] = true;
yootee 3:a9b4b2565a23 259 wait_data_[port] = false;
yootee 3:a9b4b2565a23 260 tmp_data_[port][0] = get_data;
yootee 3:a9b4b2565a23 261 data_count_[port]++;
yootee 3:a9b4b2565a23 262 }else if(wait_data_[port]){
yootee 3:a9b4b2565a23 263 id_ok_[port] = true;
yootee 3:a9b4b2565a23 264 tmp_data_[port][0] = get_data;
yootee 3:a9b4b2565a23 265 data_count_[port]++;
yootee 3:a9b4b2565a23 266 }else{
yootee 3:a9b4b2565a23 267 stx_flag_[port] = false;
yootee 3:a9b4b2565a23 268 }
yootee 3:a9b4b2565a23 269 rx_id_ = get_data;//メンバ変数に保存
yootee 3:a9b4b2565a23 270 }else if(serial_[port]->getc() == STX){
yootee 3:a9b4b2565a23 271 stx_flag_[port] = true;
yootee 3:a9b4b2565a23 272 data_count_[port] = 0;
yootee 3:a9b4b2565a23 273 id_ok_[port] = false;
yootee 3:a9b4b2565a23 274 //id_ok_[port] = wait_data_[port];//データ返信待ち時はidチェック無し
yootee 3:a9b4b2565a23 275 }
yootee 3:a9b4b2565a23 276 return;
yootee 3:a9b4b2565a23 277 }
yootee 3:a9b4b2565a23 278
yootee 3:a9b4b2565a23 279 void ScrpSlave::dataSend0(){
yootee 3:a9b4b2565a23 280 while(serial_[0]->writeable()){
yootee 3:a9b4b2565a23 281 if(data_count_[0] < 8){
yootee 3:a9b4b2565a23 282 serial_[0]->putc(send_data_[0][data_count_[0]++]);
yootee 3:a9b4b2565a23 283 }else{
yootee 3:a9b4b2565a23 284 serial_[0]->attach(NULL, Serial::TxIrq);
yootee 3:a9b4b2565a23 285 if(mode_%2 == 1){
yootee 3:a9b4b2565a23 286 rede_->write(0);
yootee 3:a9b4b2565a23 287 }
yootee 3:a9b4b2565a23 288 break;
yootee 3:a9b4b2565a23 289 }
yootee 3:a9b4b2565a23 290 }
yootee 3:a9b4b2565a23 291 }
yootee 3:a9b4b2565a23 292
yootee 3:a9b4b2565a23 293 void ScrpSlave::dataSend1(){
yootee 3:a9b4b2565a23 294 while(serial_[1]->writeable()){
yootee 3:a9b4b2565a23 295 if(data_count_[1] < 8){
yootee 3:a9b4b2565a23 296 serial_[1]->putc(send_data_[1][data_count_[1]++]);
yootee 3:a9b4b2565a23 297 }else{
yootee 3:a9b4b2565a23 298 serial_[1]->attach(NULL, Serial::TxIrq);
yootee 3:a9b4b2565a23 299 break;
yootee 3:a9b4b2565a23 300 }
yootee 3:a9b4b2565a23 301 }
yootee 3:a9b4b2565a23 302 }
yootee 3:a9b4b2565a23 303
yootee 3:a9b4b2565a23 304 void ScrpSlave::prime(int port){
yootee 3:a9b4b2565a23 305 serial_[port]->attach(NULL, Serial::TxIrq);
yootee 3:a9b4b2565a23 306 data_count_[port] = 0;
yootee 3:a9b4b2565a23 307 if(port == 0){
yootee 3:a9b4b2565a23 308 if(mode_%2 == 1){
yootee 3:a9b4b2565a23 309 rede_->write(1);
yootee 3:a9b4b2565a23 310 }
yootee 3:a9b4b2565a23 311 dataSend0();
yootee 3:a9b4b2565a23 312 serial_[0]->attach(callback(this, &ScrpSlave::dataSend0), Serial::TxIrq);
yootee 3:a9b4b2565a23 313 }else{
yootee 3:a9b4b2565a23 314 dataSend1();
yootee 3:a9b4b2565a23 315 serial_[1]->attach(callback(this, &ScrpSlave::dataSend1), Serial::TxIrq);
yootee 3:a9b4b2565a23 316 }
yootee 3:a9b4b2565a23 317 }
yootee 3:a9b4b2565a23 318
yootee 3:a9b4b2565a23 319 ScrpSlave::~ScrpSlave(){
yootee 3:a9b4b2565a23 320 delete flash_;
yootee 3:a9b4b2565a23 321 if(mode_%2 == 1){
yootee 3:a9b4b2565a23 322 delete rede_;
yootee 3:a9b4b2565a23 323 }
yootee 3:a9b4b2565a23 324 }