dg600f.cpp (4672B)
1 #include "dg600f.hpp" 2 #include <cstring> 3 #include <iostream> 4 #include <termios.h> 5 #include <chrono> 6 #include <unistd.h> 7 8 int DG600F::configGPIO(){ 9 gpioChip = new ::gpiod::chip(GPIO_CHIP); 10 gpioInhibitLine = gpioChip->find_line(GPIO_LINE); 11 ::gpiod::line_request inhibitLineConfig = { 12 "cash2ecash_dg600f_inhibit", 13 ::gpiod::line_request::DIRECTION_OUTPUT, 14 ::gpiod::line_request::FLAG_BIAS_DISABLE 15 }; 16 17 gpioInhibitLine.request(inhibitLineConfig,0); 18 19 20 return 0; 21 } 22 23 int DG600F::configSerial(int fd, int baudrate){ 24 struct termios t; 25 if (tcgetattr(fd, &t) != 0){ 26 std::cerr << "Error from tcgattr: " << strerror(errno) << std::endl; 27 return -1; 28 } 29 cfsetispeed(&t, baudrate); 30 31 t.c_cflag = (t.c_cflag & ~CSIZE) | CS8; //Configure 8 databits 32 t.c_iflag = t.c_iflag &= ~IGNBRK; //Disable break processing 33 t.c_lflag = 0; //no signaling chars, no echo, no canonical processing 34 t.c_cc[VMIN] = 0; //set minimum character for noncanonical read to 0 35 t.c_cc[VTIME] = 1; //Set read timeout for noncanonical read to 0.1 seconds 36 t.c_iflag = ~(IXON | IXOFF| IXANY); // shut off xon/xoff ctrl 37 t.c_cflag |= (CLOCAL | CREAD); // ignore modem controls enable reading 38 t.c_cflag |= PARENB; //enable parity 39 t.c_cflag &= ~PARODD; //set parity to even 40 t.c_cflag &= ~CSTOPB; //disable two stop bits 41 42 if (tcsetattr(fd, TCSANOW, &t) != 0) { 43 std::cerr << "Error from tcsetattr: " << strerror(errno) 44 << std::endl; 45 return -1; 46 } 47 return 0; 48 } 49 50 int DG600F::releaseHardware(){ 51 gpioInhibitLine.release(); 52 close(fd); 53 return 0; 54 } 55 56 int DG600F::clearAccumulatedAmount() { 57 accumulatedAmount_mutex.lock(); 58 accumulatedAmmount.fraction = 0; 59 accumulatedAmmount.value = 0; 60 accumulatedAmount_mutex.unlock(); 61 return 0; 62 } 63 64 void DG600F::serialListenThread(int fd){ 65 int readbytes = 0; 66 char buffer[32]; 67 TALER_Amount tempAmount; 68 int i; 69 while (true == flagSerialListenRun) { 70 readbytes = read(fd, buffer, 32); 71 if(0 > readbytes){ 72 std::cerr << "Error Reading from serial Interface" << strerror(readbytes) << std::endl; 73 return; 74 } 75 fifo_mutex.lock(); 76 accumulatedAmount_mutex.lock(); 77 for (i=0; i < readbytes; i++) { 78 tempAmount = convertAmount(buffer[i]); 79 amountFIFO.push_back(tempAmount); 80 //TODO Errorhandling 81 strcpy(accumulatedAmmount.currency, currency); 82 TALER_amount_add(&accumulatedAmmount, &accumulatedAmmount, &tempAmount); 83 } 84 fifo_mutex.unlock(); 85 accumulatedAmount_mutex.unlock(); 86 std::this_thread::sleep_for(std::chrono::milliseconds(200)); 87 } 88 } 89 90 91 int DG600F::startMoneyAcceptance(){ 92 //Clear read amounts... 93 clearAccumulatedAmount(); 94 fifo_mutex.lock(); 95 amountFIFO.clear(); 96 fifo_mutex.unlock(); 97 //Clear buffer of serial driver 98 char trash; 99 while (true) { 100 int readbytes; 101 readbytes = read(fd, &trash, 1); 102 if (0 > readbytes){ 103 std::cerr << "Error trying to read from char device" << strerror(readbytes) << std::endl; 104 }else if (0 == readbytes) { 105 break; 106 } 107 std::cout << "clearing trash" << std::endl; 108 } 109 // 110 gpioInhibitLine.set_value(1); 111 //Start thread which waits for chars... 112 flagSerialListenRun = true; 113 std::thread tr(&DG600F::serialListenThread, this, this->fd); 114 tr.detach(); 115 return 0; 116 } 117 118 int DG600F::stopMoneyAcceptance(){ 119 flagSerialListenRun = false; 120 gpioInhibitLine.set_value(0); 121 return 0; 122 } 123 124 125 int DG600F::readAccumulated(TALER_Amount *retval) { 126 accumulatedAmount_mutex.lock(); 127 *retval = accumulatedAmmount; 128 accumulatedAmount_mutex.unlock(); 129 return 0; 130 } 131 132 int DG600F::readFIFO(TALER_Amount *retval){ 133 fifo_mutex.lock(); 134 if (not amountFIFO.empty()){ 135 *retval = *amountFIFO.begin(); 136 amountFIFO.erase(amountFIFO.begin()); 137 } 138 fifo_mutex.unlock(); 139 return 0; 140 } 141 142 143 TALER_Amount DG600F::convertAmount(char amount){ 144 TALER_Amount talAmount; 145 strcpy(talAmount.currency, currency); 146 switch (amount) { 147 case DG600FCHF0_1: 148 talAmount.fraction = 10000000; 149 talAmount.value = 0; 150 break; 151 case DG600FCHF0_2: 152 talAmount.value = 0; 153 talAmount.fraction = 20000000; 154 break; 155 case DG600FCHF0_5: 156 talAmount.value = 0; 157 talAmount.fraction = 50000000; 158 break; 159 case DG600FCHF1: 160 talAmount.fraction = 0; 161 talAmount.value = 1; 162 break; 163 case DG600FCHF2: 164 talAmount.fraction = 0; 165 talAmount.value = 2; 166 break; 167 case DG600FCHF5: 168 talAmount.fraction = 0; 169 talAmount.value = 5; 170 break; 171 default: 172 std::cerr << "Received char" << amount << std::endl; 173 std::cerr << "Unknown Coin value, returning amount 0..." << std::endl; 174 talAmount.fraction = 0; 175 talAmount.value = 0; 176 } 177 return talAmount; 178 } 179 180 181 182