PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/internal/EepromInternal.cpp

https://github.com/amcjen/ncore
C++ | 217 lines | 142 code | 48 blank | 27 comment | 31 complexity | b31a020274fd8eee9c4b7708dac15b7f MD5 | raw file
  1. // STL includes
  2. #include <string>
  3. #include <vector>
  4. #include <iostream>
  5. #include <stdexcept>
  6. #include <sstream>
  7. #include <iomanip>
  8. #include <iterator>
  9. // C includes
  10. // Library includes
  11. // Project includes
  12. #include <Logger.h>
  13. #include <Parser.h>
  14. #include <EepromInternal.h>
  15. using namespace std;
  16. /****************************************************************************/
  17. // eeprom size must always be a power of 2
  18. static const int eeprom_size = 1 << 10;
  19. /****************************************************************************/
  20. Eeprom::Eeprom(Logger& _log): log(_log)
  21. {
  22. clear();
  23. }
  24. /****************************************************************************/
  25. void Eeprom::clear(void)
  26. {
  27. values.clear();
  28. values.resize(eeprom_size);
  29. }
  30. /****************************************************************************/
  31. size_t Eeprom::size(void)
  32. {
  33. return values.size();
  34. }
  35. /****************************************************************************/
  36. uint8_t Eeprom::readByte(int addr) const
  37. {
  38. uint8_t result = values.at(addr);
  39. log.sketch("EEPR","%i read %u",addr,result);
  40. return result;
  41. }
  42. /****************************************************************************/
  43. void Eeprom::writeByte(int addr, uint8_t value)
  44. {
  45. log.sketch("EEPR","%i write %u",addr,value);
  46. values.at(addr) = value;
  47. }
  48. /****************************************************************************/
  49. std::string& Eeprom::getCommands(void) const
  50. {
  51. static string commands = "eeprom ee";
  52. return commands;
  53. }
  54. /****************************************************************************/
  55. bool Eeprom::runCommand( const Parser& parser )
  56. {
  57. bool result = false;
  58. const string& command = parser.at(0);
  59. if ( command == "eeprom" || command == "ee" )
  60. {
  61. result = command_eeprom(parser);
  62. }
  63. else if ( command == "help" )
  64. {
  65. const string& helpcommand = parser.at(1);
  66. if ( helpcommand == "eeprom" )
  67. {
  68. cout << "eeprom <addr> -- read one byte" << endl;
  69. cout << "eeprom <addr> len <len> -- read <len> bytes" << endl;
  70. cout << "eeprom <addr> write <xx> ... <xx> -- write hex bytes to eeprom" << endl;
  71. }
  72. result = true;
  73. }
  74. return result;
  75. }
  76. /****************************************************************************/
  77. static int get_number(vector<string>::const_iterator current,vector<string>::const_iterator end )
  78. {
  79. int result = 0;
  80. if ( current == end )
  81. throw new runtime_error("Expecting value");
  82. char c = (*current)[0];
  83. if ( c < '0' || c > '9' )
  84. throw new runtime_error("Expecing numeric value");
  85. istringstream ss(*current);
  86. ss >> result;
  87. return result;
  88. }
  89. /****************************************************************************/
  90. static int get_hex_number(vector<string>::const_iterator current,vector<string>::const_iterator /*end*/ )
  91. {
  92. int result = 0;
  93. /* Unreachable code
  94. if ( current == end )
  95. throw new runtime_error("Expecting value");
  96. */
  97. char c = (*current)[0];
  98. if ( ( c < '0' || c > '9' ) && ( c < 'a' || c > 'f' ) )
  99. throw new runtime_error("Expecing hexnumeric value");
  100. istringstream ss(*current);
  101. ss >> hex >> result;
  102. return result;
  103. }
  104. /****************************************************************************/
  105. bool Eeprom::command_eeprom(const std::vector<std::string>& _commands)
  106. {
  107. vector<string>::const_iterator current = _commands.begin() + 1;
  108. int addr = get_number(current++,_commands.end());
  109. if ( addr < 0 || addr >= eeprom_size )
  110. throw new runtime_error("Address out of range");
  111. if ( current == _commands.end() )
  112. {
  113. // read one byte
  114. cout << "EEPROM @ " << addr << " is " << hex << setfill('0') << setw(2) << (int)values.at(addr) << endl;
  115. }
  116. else
  117. {
  118. const string& operand = *current++;
  119. if ( operand == "len" )
  120. {
  121. // read len bytes
  122. int length = get_number(current++,_commands.end());
  123. cout << "EEPROM @ " << addr << " for " << dec << length << " are " << hex ;
  124. while( length-- )
  125. cout << setfill('0') << setw(2) << (int)values.at(addr++) << " ";
  126. cout << endl;
  127. }
  128. else if ( operand == "write" )
  129. {
  130. // write all the following bytes
  131. if ( current == _commands.end() )
  132. throw new runtime_error("Expecting at least one value to write");
  133. ostringstream message;
  134. message << addr << " write ";
  135. while ( current != _commands.end() )
  136. {
  137. int value = get_hex_number(current++,_commands.end());
  138. message << hex << setfill('0') << setw(2) << value << " ";
  139. values.at(addr++) = value;
  140. }
  141. cout << "EEPROM @ " << message.str() << endl;
  142. log.internal("EEPR",message.str());
  143. }
  144. else
  145. throw new runtime_error("Unknown sub-command");
  146. }
  147. return true;
  148. }
  149. /****************************************************************************/
  150. ostream& operator<<(ostream& os, const Eeprom& eep)
  151. {
  152. copy(eep.begin(),eep.end(),ostream_iterator<uint8_t>(os));
  153. return os;
  154. }
  155. /****************************************************************************/
  156. istream& operator>>(istream& is, Eeprom& eep)
  157. {
  158. eep.clear();
  159. int addr = 0;
  160. int val = is.get();
  161. while ( is.good() )
  162. {
  163. eep.writeByte( addr++, val );
  164. val = is.get();
  165. }
  166. return is;
  167. }
  168. /****************************************************************************/
  169. // vim:cin:ai:sts=2 sw=2 ft=cpp