This is going to be a long post. It is parts of the Arduino code that runs the flash programmer and bus. SetupLoop.cpp

 1 #include "Flash.h"
 2 #include "serialIF.h"
 3 #include "Interpreter.h"
 4 #include "Arduino.h"
 5 #include "CPLD.h"
 6 
 7 // Arduino uses 'setup' and 'loop' instead of 'main'
 8 
 9 void setup() {
10 
11     pinMode(13, OUTPUT);
12 
13     // Blink LED twice
14     digitalWrite(13, HIGH);
15     delay(500);
16     digitalWrite(13, LOW);
17     delay(500);
18     digitalWrite(13, HIGH);
19     delay(500);
20     digitalWrite(13, LOW);
21 }
22 
23 void loop() {
24 
25     Interpreter interpreter;
26     interpreter.Loop();
27 
28 }

SerialIF.h

 1 #ifndef INCLUDE_SERIALIF_H
 2 #define INCLUDE_SERIALIF_H
 3 #include <stdint.h>
 4 
 5 // The SerialIF class provides application level access to communication facilities
 6 // c must be:
 7 //      > command
 8 //      < response
 9 //      ! text
10 //      $ payload
11 //      . ready for payload
12 // Each exchange has an id
13 // packet ID is used for payloads
14 class SerialIF
15 {
16  public:
17      SerialIF();
18      ~SerialIF();
19 
20 public:
21     // Basic send. See class doc for 'c'. response is a buffer of up to 256. length is 1-256, 
22     bool Send(char c, const uint8_t* response, int16_t length, uint8_t id, uint16_t packetId);
23 
24     // Basic send. See class doc for 'c'. buffer is a buffer of 256 bytes. length is 1-256, 
25     int16_t Receive(char *pC, uint8_t* buffer, uint8_t* pId, uint16_t *pPacketId);
26 };
27 
28 #endif
29 
30 </stdint>

SerialIF.cpp

  1 #include "SerialIF.h"
  2 #include <arduino.h>
  3 
  4 #define HEADER_LENGTH (6)
  5 #define TIMEOUT (10000)
  6 #define BAUD_RATE (9600)
  7 
  8 ///////////////////////////////////////////////////////////////////////////////
  9 //
 10 //      Object section
 11 //
 12 
 13 SerialIF::SerialIF()
 14 {
 15     Serial.begin(BAUD_RATE);
 16     Serial.setTimeout(TIMEOUT);
 17 }
 18 
 19 SerialIF::~SerialIF()
 20 {
 21     Serial.end();
 22 }
 23 
 24 ///////////////////////////////////////////////////////////////////////////////
 25 //
 26 //      Low Level Read/Write section
 27 //
 28 
 29 // A single communication consists of a header and the data
 30 // Header is 6 bytes:
 31 //      [0] A character:
 32 //          '>' PC to Arduino command
 33 //          '<' Arduino to PC response
 34 //          '!' In progess Arduino -> PC text
 35 //          '$' Payload packet (256 bytes unless the last one)
 36 //          '.' OK to send next payload packet
 37 //      [1] length 1-255, 0 means 256
 38 //      [2] 8 bit transaction id
 39 //      [3] sum adjustment. Adjust this so the sum of header and data is 0xff
 40 //      [4] 2 byte packet # high byte
 41 //      [5] 2 byte packet # low byte
 42 //
 43 //  The header is hidden from the interface. The user simply used the 'command', 'response', 
 44 //  'eventString', or 'buffer' and the proper calling function
 45 //
 46 
 47 bool SerialIF::Send(char c, const uint8_t* response, int16_t length, uint8_t id, uint16_t packetId)
 48 {
 49     // Setup up header
 50     uint8_t header[HEADER_LENGTH];
 51     header[0] = c;
 52     header[1] = (uint8_t)length; // 256 converts to 0 in cast
 53     header[2] = id;
 54     header[3] = 0;
 55     header[4] = (byte)(packetId >> 8);
 56     header[5] = (byte)packetId;
 57 
 58     // Determine sum for error checking
 59     uint8_t sum = 0;
 60     for (int16_t i = 0; i < HEADER_LENGTH; i++)
 61     {
 62         sum += header[i];
 63     }
 64     for (int16_t i = 0; i < length; i++)
 65     {
 66         sum += response[i];
 67     }
 68     header[3] = (uint8_t)~sum;
 69     
 70     // ensure it all gets send
 71     const uint8_t* p = header;
 72     int len = HEADER_LENGTH;
 73     int sent = 0;
 74     while (sent < len)
 75     {
 76         int got = Serial.write(p, len - sent);
 77         if (got < 0 || got > len - sent)
 78         {
 79             digitalWrite(13, HIGH);
 80             return false;
 81         }
 82         sent += got;
 83         p += got;
 84     }
 85     len = length;
 86     p = response;
 87     sent = 0;
 88     while (sent < len)
 89     {
 90         int got = Serial.write(p, len - sent);
 91         if (got < 0 || got > len - sent)
 92         {
 93             digitalWrite(13, HIGH);
 94             return false;
 95         }
 96         sent += got;
 97         p += got;
 98     }
 99     return true;
100 }
101 
102 int16_t SerialIF::Receive(char *pC, uint8_t* buffer, uint8_t* pId, uint16_t *pPacketId)
103 {
104     uint32_t stopOn = millis() + TIMEOUT;
105     int16_t received = 0;
106     int16_t expecting = HEADER_LENGTH;
107     uint8_t header[HEADER_LENGTH];
108     uint8_t* p;
109 
110     // Get header
111     p = &header[0];
112     while (millis() < stopOn && received < expecting)
113     {
114         size_t got = Serial.readBytes(p, expecting - received);
115         if (got > (size_t)(expecting - received))
116         {
117             digitalWrite(13, HIGH);
118             return -1;
119         }
120         p += got;
121         received += got;
122     }
123 
124     if (received == expecting)
125     {
126         // extract the type character
127         *pC = header[0];
128 
129         // get the data size
130         expecting = header[1];
131         if (expecting == 0)
132         {
133             expecting = 256;
134         }
135 
136         // get the ID
137         *pId = header[2]; // return to user
138         *pPacketId = (header[4] << 8) | header[5];
139     }
140     else
141     {
142         return -1;
143     }
144 
145     // Get the data portion
146     p = buffer;
147     *p = 'x'; // destroy first data
148     received = 0;
149     while (millis() < stopOn && received < expecting)
150     {
151         size_t got = Serial.readBytes(p, expecting - received);
152         if (got > (size_t)(expecting - received))
153         {
154             digitalWrite(13, HIGH);
155             return -1;
156         }
157         received += got;
158         p += got;
159     }
160 
161     if (received == expecting)
162     {
163         // ensure the sum is 255
164         uint8_t sum = 0;
165         for (int16_t i = 0; i < HEADER_LENGTH; ++i)
166         {
167             sum += header[i];
168         }
169         for (int16_t i = 0; i < expecting; ++i)
170         {
171             sum += buffer[i];
172         }
173         if (sum != 255)
174         {
175             return -1;
176         }
177     }
178     else
179     {
180         return -1;
181     }
182 
183     return received;
184 }
185 
186 </arduino>

CPLD.h

 1 #ifndef INCLUDE_CPLD_H
 2 #define INCLUDE_CPLD_H
 3 #include <stdint.h>
 4 
 5 // The CPLD class handles low level access to the CPLD which controls the 39SF020A flash device
 6 class CPLD
 7 {
 8 protected:
 9     CPLD();
10 
11     // Send CPLD reset sequence
12     void ResetSequence();
13 
14     // Update address bits 3:0
15     void UpdateAddress_3_0(uint32_t addr);
16 
17     // Update address bits 7:4
18     void UpdateAddress_7_4(uint32_t addr);
19 
20     // Update address bits 17:8
21     void UpdateAddress_17_8(uint32_t addr);
22 
23     // Update chip control where bits 3-0 are drive, CS*, WR*, and RD*
24     void UpdateChip(int16_t chip);
25 
26     // Update the CTRL register that tells which register to pulse data in and out
27     void UpdateCtrl(int16_t ctrl);
28 
29     // Swaps a data byte on Din/Dout
30     uint8_t ReadWrite(uint8_t data);
31 
32     // Pulse CLK high and low
33     void PulseClk();
34 
35     // Pulse nCTRL low and high
36     void PulseCtrl();
37 
38 public:
39     // Control pins directly
40     bool DirectWrite(uint16_t mask, uint16_t values);
41 
42     // Read current state of pins
43     bool DirectRead(uint16_t mask, uint16_t* pValues);
44 
45 private:
46     // Update an arbitrary part of the address bits
47     void UpdateAddress_start_end(uint32_t addr, int16_t startBit, int16_t endBit);
48 
49     // Keep track of last control address to know which parts to avoid shifting out
50     int16_t m_lastCtrl;
51 
52 public:
53     static const int16_t PIN_nCTRL = 2;
54     static const int16_t PIN_Dout = 3;
55     static const int16_t PIN_Din = 4;
56     static const int16_t PIN_CLK = 5;
57     static const int16_t PIN_ENABLE = 6;
58 };
59 
60 #endif

CPLD.cpp

  1 #include <arduino.h>
  2 #include "CPLD.h"
  3 
  4 // Adds delay if necessary for viewing pins with DMM
  5 #define SUPER_SLO_MO()
  6 
  7 #define LAST_CTRL_INIT (-1)
  8 
  9 CPLD::CPLD()
 10 {
 11     m_lastCtrl = LAST_CTRL_INIT;
 12 }
 13 
 14 ///////////////////////////////////////////////////////////////////////////////
 15 //
 16 //      Reset section
 17 //
 18 
 19 void CPLD::ResetSequence()
 20 {
 21     // initialize pins before setting output mode
 22     digitalWrite(PIN_ENABLE, HIGH);
 23     digitalWrite(PIN_CLK, HIGH);
 24     digitalWrite(PIN_nCTRL, HIGH);
 25     digitalWrite(PIN_Din, HIGH);
 26 
 27     // set pin modes
 28     pinMode(PIN_ENABLE, OUTPUT);
 29     pinMode(PIN_nCTRL, OUTPUT);
 30     pinMode(PIN_Dout, INPUT);
 31     pinMode(PIN_Din, OUTPUT);
 32     pinMode(PIN_CLK, OUTPUT);
 33 
 34     // Execute reset sequence
 35     PulseClk();
 36     PulseClk();
 37     digitalWrite(PIN_nCTRL, LOW);
 38     delayMicroseconds(1);
 39     PulseClk();
 40     PulseClk();
 41     PulseClk();
 42     digitalWrite(PIN_nCTRL, HIGH);
 43     digitalWrite(PIN_nCTRL, HIGH);
 44     delayMicroseconds(1);
 45     SUPER_SLO_MO();
 46     digitalWrite(PIN_ENABLE, LOW);
 47     delayMicroseconds(1);
 48     SUPER_SLO_MO();
 49 }
 50 
 51 ///////////////////////////////////////////////////////////////////////////////
 52 //
 53 //      Address Shift Register section
 54 //
 55 
 56 void CPLD::UpdateAddress_3_0(uint32_t addr)
 57 {
 58     UpdateCtrl(0x01);
 59     UpdateAddress_start_end(addr, 3, 0);
 60 }
 61 
 62 void CPLD::UpdateAddress_7_4(uint32_t addr)
 63 {
 64     UpdateCtrl(0x02);
 65     UpdateAddress_start_end(addr, 7, 4);
 66 }
 67 
 68 void CPLD::UpdateAddress_17_8(uint32_t addr)
 69 {
 70     UpdateCtrl(0x03);
 71     UpdateAddress_start_end(addr, 17, 8);
 72 }
 73 void CPLD::UpdateAddress_start_end(uint32_t addr, int16_t endBit, int16_t startBit)
 74 {
 75     int16_t i;
 76     for (i = startBit; i <= endBit; ++i)
 77     {
 78         uint32_t mask = 1L << i;
 79         digitalWrite(PIN_Din, (addr & mask) ? HIGH : LOW);
 80         digitalWrite(PIN_Din, (addr & mask) ? HIGH : LOW); // delay
 81         SUPER_SLO_MO();
 82         PulseClk();
 83     }
 84 }
 85 
 86 // Chip bits are:
 87 //  3   drive id not nRD low, or read on rising edge
 88 //  2   nCS
 89 //  1   nWR
 90 //  0   nRD
 91 void CPLD::UpdateChip(int16_t chip)
 92 {
 93     int16_t i;
 94     UpdateCtrl(0x07);
 95     for (i = 0; i < 4; ++i)
 96     {
 97         digitalWrite(PIN_Din, (chip & 1) ? HIGH : LOW);
 98         digitalWrite(PIN_Din, (chip & 1) ? HIGH : LOW); // delay
 99         SUPER_SLO_MO();
100         PulseClk();
101         chip >>= 1;
102     }
103     PulseCtrl();
104 }
105 
106 ///////////////////////////////////////////////////////////////////////////////
107 //
108 //      CPLD Control section
109 //
110 
111 // Control register
112 void CPLD::UpdateCtrl(int16_t ctrl)
113 {
114     int16_t i;
115     digitalWrite(PIN_nCTRL, LOW);
116     SUPER_SLO_MO();
117     if (true || m_lastCtrl != ctrl)
118     {
119         m_lastCtrl = ctrl;
120         for (i = 0; i < 3; ++i)
121         {
122             int16_t bit = ctrl & 1;
123             ctrl = ctrl >> 1;
124             digitalWrite(PIN_Din, bit ? HIGH : LOW);
125             digitalWrite(PIN_Din, bit ? HIGH : LOW); // delay
126             SUPER_SLO_MO();
127             PulseClk();
128         }
129     }
130     else
131     {
132         delayMicroseconds(1);
133     }
134     digitalWrite(PIN_nCTRL, HIGH);
135     SUPER_SLO_MO();
136 }
137 
138 // clock exchange 8 bits on 'data'->Din and Dout->return.
139 uint8_t CPLD::ReadWrite(uint8_t data)
140 {
141     int16_t i;
142     uint8_t outData = 0;
143     UpdateCtrl(0x00);
144     for (i = 0; i < 8; ++i)
145     {
146         digitalWrite(PIN_Din, (data & 1) ? HIGH : LOW);
147         digitalWrite(PIN_Din, (data & 1) ? HIGH : LOW); // delay
148         SUPER_SLO_MO();
149         PulseClk();
150         outData >>= 1;
151         if (digitalRead(PIN_Dout) == HIGH)
152         {
153             outData |= 0x80;
154         }
155         data >>= 1;
156     }
157     return outData;
158 }
159 
160 // Brings clk high then low
161 void CPLD::PulseClk()
162 {
163     digitalWrite(PIN_CLK, HIGH);
164     digitalWrite(PIN_CLK, HIGH); // delay
165     SUPER_SLO_MO();
166     digitalWrite(PIN_CLK, LOW);
167     digitalWrite(PIN_CLK, LOW); // delay
168     SUPER_SLO_MO();
169 }
170 
171 // Brings nCTRL low then high -- Use to strobe bus control
172 void CPLD::PulseCtrl()
173 {
174     digitalWrite(PIN_nCTRL, LOW);
175     digitalWrite(PIN_nCTRL, LOW); // delay
176     SUPER_SLO_MO();
177     digitalWrite(PIN_nCTRL, HIGH);
178     digitalWrite(PIN_nCTRL, HIGH); // delay
179     SUPER_SLO_MO();
180 }
181 
182 ///////////////////////////////////////////////////////////////////////////////
183 //
184 //      Direct Arduino Pin Access section
185 //
186 
187 bool CPLD::DirectWrite(uint16_t mask, uint16_t values)
188 {
189     for (int i = 0; i < 13; i++)
190     {
191         uint16_t bit = 1 << i;
192         if (mask & bit)
193         {
194             digitalWrite(i, (values & bit) ? (HIGH) : (LOW));
195         }
196     }
197     return true;
198 }
199 
200 bool CPLD::DirectRead(uint16_t mask, uint16_t* pValues)
201 {
202     *pValues = 0;
203     for (int i = 0; i < 13; i++)
204     {
205         uint16_t bit = 1 << i;
206         if (mask & bit)
207         {
208             if (digitalRead(i))
209             {
210                 *pValues |= bit;
211             }
212         }
213     }
214     return true;
215 }
216 
217 </arduino>

Bus.h

 1 #ifndef INCLUDE_BUS_H
 2 #define INCLUDE_BUS_H
 3 #include <stdint.h>
 4 #include "CPLD.h"
 5 
 6 // The Bus class provides access to the bus on the output of the CPLD
 7 class Bus : public CPLD
 8 {
 9 public:
10     Bus();
11     ~Bus();
12 
13     // Sets the input/output pin mode
14     virtual bool EnablePins(bool enable);
15 
16     // Resets the Bus
17     virtual bool Reset(bool force);
18 
19     // Write data to *ptr.
20     // NOTE: This is a NOT toggle bit operation, just sends data to *ptr
21     // returns true if successful
22     void Write(uint32_t ptr, uint8_t data);
23 
24     // Read data at *ptr into *pData
25     // returns true if successful
26     void Read(uint32_t, uint8_t* pData);
27 
28     // Read data at last *ptr into *pData
29     // returns true if successful
30     void Read(uint8_t* pData);
31 
32     // Updates entire address bus
33     void UpdateAddress(uint32_t addr);
34 
35 protected:
36     // Update address bits only on parts that are different
37     void UpdateAddressDiff(uint32_t addr);
38 
39     // Pulse RD
40     void PulseRD();
41 
42     // Pulse WR
43     void PulseWR();
44 
45 private:
46     // Keep track of last programmed address to know which parts to avoid shifting out
47     uint32_t m_lastAddr;
48 
49     // Keep track of whether the CPLD has been reset
50     bool m_reset;
51 };
52 
53 #endif

Bus.cpp

  1 #include <arduino.h>
  2 #include "Bus.h"
  3 
  4 #define LAST_ADDR_INIT (0xffffffff)
  5 
  6 Bus::Bus() : CPLD()
  7 {
  8     m_lastAddr = LAST_ADDR_INIT;
  9     m_reset = false;
 10 }
 11 
 12 Bus::~Bus()
 13 {
 14 }
 15 
 16 ///////////////////////////////////////////////////////////////////////////////
 17 //
 18 //      Reset section
 19 //
 20 
 21 bool Bus::Reset(bool force)
 22 {
 23     if (force || !m_reset)
 24     {
 25         ResetSequence();
 26 
 27         m_lastAddr = LAST_ADDR_INIT;
 28         m_reset = true;
 29     }
 30     return true;
 31 }
 32 
 33 bool Bus::EnablePins(bool enable)
 34 {
 35     if (enable)
 36     {
 37         pinMode(PIN_ENABLE, OUTPUT);
 38         pinMode(PIN_nCTRL, OUTPUT);
 39         pinMode(PIN_Dout, INPUT);
 40         pinMode(PIN_Din, OUTPUT);
 41         pinMode(PIN_CLK, OUTPUT);
 42     }
 43     else
 44     {
 45         // TODO when pullups are on board, make all these revert to INPUT
 46         pinMode(PIN_ENABLE, INPUT_PULLUP);
 47         pinMode(PIN_nCTRL, INPUT_PULLUP);
 48         pinMode(PIN_Dout, INPUT);
 49         pinMode(PIN_Din, INPUT_PULLUP);
 50         pinMode(PIN_CLK, INPUT_PULLUP);
 51     }
 52     return true;
 53 }
 54 
 55 
 56 ///////////////////////////////////////////////////////////////////////////////
 57 //
 58 //      Basic Operation section
 59 //
 60 
 61 
 62 void Bus::Write(uint32_t addr, uint8_t data)
 63 {
 64     UpdateAddressDiff(addr);
 65     ReadWrite(data);
 66     PulseWR();
 67 }
 68 
 69 void Bus::Read(uint32_t addr, uint8_t* pData)
 70 {
 71     UpdateAddressDiff(addr);
 72     PulseRD();
 73     *pData = ReadWrite(0);
 74 }
 75 
 76 void Bus::Read(uint8_t* pData)
 77 {
 78     PulseRD();
 79     *pData = ReadWrite(0);
 80 }
 81 
 82 ///////////////////////////////////////////////////////////////////////////////
 83 //
 84 //      Address Shift Register section
 85 //
 86 
 87 // Updates entire address bus
 88 void Bus::UpdateAddress(uint32_t addr)
 89 {
 90     UpdateAddress_3_0(addr);
 91     UpdateAddress_7_4(addr);
 92     UpdateAddress_17_8(addr);
 93 }
 94 
 95 // Updates address bus shifting only those shift registers that have changed
 96 void Bus::UpdateAddressDiff(uint32_t addr)
 97 {
 98     if (m_lastAddr == LAST_ADDR_INIT)
 99     {
100         UpdateAddress(addr);
101     }
102     else
103     {
104         uint32_t diffs = (uint32_t)(addr ^ m_lastAddr);
105         if (diffs & 0x0000f)
106         {
107             UpdateAddress_3_0(addr);
108         }
109         if (diffs & 0x000f)
110         {
111             UpdateAddress_7_4(addr);
112         }
113         if (diffs & 0x3ff00UL)
114         {
115             UpdateAddress_17_8(addr);
116         }
117     }
118 }
119 
120 ///////////////////////////////////////////////////////////////////////////////
121 //
122 //      Bus Control Control section
123 //
124 
125 //  D[7:0]  -------------------------
126 //  nCS     ^^^\_________________/^^^
127 //  nRD     ^^^\_________________/^^^
128 //  nWR     ^^^^^^^^^^^^^^^^^^^^^^^^^
129 //  read                   *
130 //  Reads when drive goes high (*)
131 void Bus::PulseRD()
132 {
133     UpdateChip(0xa); // CS, RD
134     UpdateChip(0x2); // drive, CS, RD
135     UpdateChip(0xa); // CS, RD
136     UpdateChip(0xf); // done
137 }
138 
139 //  D[7:0]  -[                     ]-
140 //  nCS     ^^^\_________________/^^^
141 //  nRD     ^^^^^^^^^^^^^^^^^^^^^^^^^
142 //  nWR     ^^^^^^^\_________/^^^^^^^
143 //  Writes when nWR goes low
144 void Bus::PulseWR()
145 {
146     UpdateChip(0x3); // drive, CS
147     UpdateChip(0x1); // drive, CS, WR
148     UpdateChip(0x3); // drive, CS
149     UpdateChip(0xf); // done
150 }

Flash.h

 1 #ifndef INCLUDE_FLASH_H
 2 #define INCLUDE_FLASH_H
 3 
 4 #include "Bus.h"
 5 
 6 // The Flash class handles application level interface to the flash
 7 class Flash
 8 {
 9 public:
10     Flash(Bus& bus);
11 
12     // Resets the CPLD
13     bool ForceReset();
14 
15     // Resets the CPLD if it hasn't been reset yet
16     bool Reset();
17 
18     // Programs data to *ptr.
19     // NOTE: This is a toggle bit operation
20     // i.e. it puts the flash into byte program mode
21     // and waits for the flash to finish
22     // returns true if successful
23     bool Program(uint32_t addr, uint8_t data);
24 
25     // Read data at *ptr into *pData
26     // returns true if successful
27     bool Read(uint32_t addr, uint8_t* pData);
28 
29     // Erases 4KB block with addr
30     // NOTE: This is a toggle bit operation
31     // returns true if successful
32     bool EraseSector(uint32_t addr);
33 
34     // Erases entire chip
35     // NOTE: This is a toggle bit operation
36     // returns true if successful
37     bool EraseChip();
38 
39 protected:
40     // Reads until the toggle bits stop toggling
41     // Returns true if the read data matches expected
42     // Use expected of 0xff for erase operations
43     bool Toggle(uint8_t expected);
44 
45 private:
46     // Low level interface
47     Bus m_bus;
48 };
49 
50 #endif

Flash.cpp

  1 #include <arduino.h>
  2 #include "Bus.h"
  3 #include "Flash.h"
  4 
  5 Flash::Flash(Bus& bus)
  6 {
  7     m_bus = bus;
  8 }
  9 
 10 ///////////////////////////////////////////////////////////////////////////////
 11 //
 12 //      Byte Access section
 13 //
 14 
 15 bool Flash::Program(uint32_t addr, uint8_t data)
 16 {
 17     m_bus.Write(0x5555, 0xaa);
 18     m_bus.Write(0x2aaa, 0x55);
 19     m_bus.Write(0x5555, 0xa0);
 20     m_bus.Write(addr, data);
 21     return Toggle(data);
 22 }
 23 
 24 bool Flash::Read(uint32_t addr, uint8_t* pData)
 25 {
 26     m_bus.Read(addr, pData);
 27     return true;
 28 }
 29 
 30 
 31 ///////////////////////////////////////////////////////////////////////////////
 32 //
 33 //      Erase section
 34 //
 35 
 36 bool Flash::EraseSector(uint32_t addr)
 37 {
 38     m_bus.Write(0x5555, 0xaa);
 39     m_bus.Write(0x2aaa, 0x55);
 40     m_bus.Write(0x5555, 0x80);
 41     m_bus.Write(0x5555, 0xaa);
 42     m_bus.Write(0x2aaa, 0x55);
 43     m_bus.Write(addr, 0x30);
 44     return Toggle(0xff);
 45     m_bus.Write(0x2aaa, 0xf0);
 46 }
 47 
 48 bool Flash::EraseChip()
 49 {
 50     m_bus.Write(0x5555, 0xaa);
 51     m_bus.Write(0x2aaa, 0x55);
 52     m_bus.Write(0x5555, 0x80);
 53     m_bus.Write(0x5555, 0xaa);
 54     m_bus.Write(0x2aaa, 0x55);
 55     m_bus.Write(0x5555, 0x10);
 56     return Toggle(0xff);
 57 }
 58 
 59 ///////////////////////////////////////////////////////////////////////////////
 60 //
 61 //      Reset section
 62 //
 63 
 64 bool Flash::Reset()
 65 {
 66     return m_bus.Reset(false);
 67 }
 68 
 69 bool Flash::ForceReset()
 70 {
 71     return m_bus.Reset(true);
 72 }
 73 
 74 ///////////////////////////////////////////////////////////////////////////////
 75 //
 76 //      Support section
 77 //
 78 
 79 bool Flash::Toggle(uint8_t expected)
 80 {
 81     bool toggling = true;
 82     uint8_t data0;
 83     uint8_t data1;
 84     m_bus.Read(&data0);
 85     while (toggling)
 86     {
 87         m_bus.Read(&data1);
 88         if ((data1 ^ data0) & 0x40)
 89         {
 90             // toggle bit toggling
 91             data0 = data1; // set up for next toggle check
 92         }
 93         else
 94         {
 95             toggling = false;
 96         }
 97     }
 98     return data1 == expected;
 99 }
100 
101 </arduino>

MCUBus.h

 1 #ifndef INCLUDE_MCUBUS_H
 2 #define INCLUDE_MCUBUS_H
 3 #include <arduino.h>
 4 #include "Bus.h"
 5 
 6 // The MCUBus class is used to allow the flash programmer to test the MCU chip before
 7 // connecting the CPU and SRAM to the bus.
 8 class MCUBus : public Bus
 9 {
10 public:
11     MCUBus();
12     ~MCUBus();
13 
14     // Sets the input/output pin mode
15     virtual bool EnablePins(bool enable);
16 
17     // Resets the Bus
18     virtual bool Reset(bool force);
19 
20     // Writes 'data' to 16 bit address 'addr'
21     bool WriteMem(uint16_t addr, uint8_t data);
22 
23     // Gets pData from 16 bit address 'addr'
24     bool FetchMem(uint16_t addr, uint8_t *pData);
25 
26     // Gets pData from 16 bit address 'addr'
27     bool ReadMem(uint16_t addr, uint8_t *pData);
28 
29     // Writes 'data' to io port 'port'
30     bool WriteIO(uint8_t port, uint8_t data);
31 
32     // Reads 'data' from io port 'port'
33     bool ReadIO(uint8_t port, uint8_t *pData);
34 
35     // Sets the HALT line
36     void HaltLine(bool level);
37 
38     // Sets the BUSACK line
39     void BusAckLine(bool level);
40 
41     // Sets the IOREQ line
42     void IOReqLine(bool level);
43 
44     // Sets the MREQ line
45     void MemReqLine(bool level);
46 
47     // Sets the M1 line
48     void M1Line(bool level);
49 
50     // Sets the CLK line
51     void Clock(bool level);
52 
53 protected:
54     void PulseIORD();
55     void PulseIOWR();
56     void PulseFetch();
57     void PulseMemRD();
58     void PulseMemWR();
59 
60 public:
61     static const int PIN_IOREQ = 7;
62     static const int PIN_MREQ = 8;
63     static const int PIN_M1 = 9;
64     static const int PIN_HALT = 10;
65     static const int PIN_BUSACK = 11;
66     static const int PIN_CLOCK = 12;
67 };
68 
69 #endif

MCUBus.cpp

  1 #include <arduino.h>
  2 #include "MCUBus.h"
  3 
  4 //#define SUPER_SLO_MO() delay(1000)
  5 #define SUPER_SLO_MO() delay(1)
  6 //#define SUPER_SLO_MO()
  7 
  8 MCUBus::MCUBus()
  9 {
 10 }
 11 
 12 MCUBus::~MCUBus()
 13 {
 14 }
 15 
 16 
 17 // Sets the input/output pin mode
 18 bool MCUBus::EnablePins(bool enable)
 19 {
 20     if (enable)
 21     {
 22         digitalWrite(PIN_HALT, HIGH);
 23         digitalWrite(PIN_MREQ, HIGH);
 24         digitalWrite(PIN_IOREQ, HIGH);
 25         digitalWrite(PIN_M1, HIGH);
 26         digitalWrite(PIN_CLOCK, HIGH);
 27         digitalWrite(PIN_BUSACK, HIGH);
 28 
 29         pinMode(PIN_HALT, OUTPUT);
 30         pinMode(PIN_MREQ, OUTPUT);
 31         pinMode(PIN_IOREQ, OUTPUT);
 32         pinMode(PIN_M1, OUTPUT);
 33         pinMode(PIN_CLOCK, OUTPUT);
 34         pinMode(PIN_BUSACK, OUTPUT);
 35     }
 36     else
 37     {
 38         // TODO when pullups are on board, make all these revert to INPUT
 39         pinMode(PIN_HALT, INPUT_PULLUP);
 40         pinMode(PIN_MREQ, INPUT_PULLUP);
 41         pinMode(PIN_IOREQ, INPUT_PULLUP);
 42         pinMode(PIN_M1, INPUT_PULLUP);
 43         pinMode(PIN_CLOCK, INPUT_PULLUP);
 44         pinMode(PIN_BUSACK, INPUT_PULLUP);
 45     }
 46     return Bus::EnablePins(enable);
 47 }
 48 
 49 // Resets the Bus
 50 bool MCUBus::Reset(bool force)
 51 {
 52     Clock(HIGH);
 53     Clock(LOW);
 54     Clock(HIGH);
 55     Clock(LOW);
 56     Clock(HIGH);
 57     Clock(LOW);
 58     return Bus::Reset(force);
 59 }
 60 
 61 
 62 bool MCUBus::WriteMem(uint16_t addr, uint8_t data)
 63 {
 64     UpdateAddressDiff(addr);
 65     ReadWrite(data);
 66     PulseMemWR();
 67     return true;
 68 }
 69 
 70 bool MCUBus::FetchMem(uint16_t addr, uint8_t *pData)
 71 {
 72     UpdateAddressDiff(addr);
 73     PulseFetch();
 74     *pData = ReadWrite(0);
 75     return true;
 76 }
 77 
 78 bool MCUBus::ReadMem(uint16_t addr, uint8_t *pData)
 79 {
 80     UpdateAddressDiff(addr);
 81     PulseMemRD();
 82     *pData = ReadWrite(0);
 83     return true;
 84 }
 85 
 86 bool MCUBus::WriteIO(uint8_t port, uint8_t data)
 87 {
 88     UpdateAddressDiff(port);
 89     ReadWrite(data);
 90     PulseIOWR();
 91     return true;
 92 }
 93 
 94 bool MCUBus::ReadIO(uint8_t port, uint8_t *pData)
 95 {
 96     UpdateAddressDiff(port);
 97     PulseIORD();
 98     *pData = ReadWrite(0);
 99     return true;
100 }
101 
102 
103 void MCUBus::HaltLine(bool level)
104 {
105     digitalWrite(PIN_HALT, level);
106 }
107 
108 void MCUBus::BusAckLine(bool level)
109 {
110     digitalWrite(PIN_BUSACK, level);
111 }
112 
113 void MCUBus::IOReqLine(bool level)
114 {
115     digitalWrite(PIN_IOREQ, level);
116 }
117 
118 void MCUBus::MemReqLine(bool level)
119 {
120     digitalWrite(PIN_MREQ, level);
121 }
122 
123 void MCUBus::M1Line(bool level)
124 {
125     digitalWrite(PIN_M1, level);
126 }
127 
128 void MCUBus::Clock(bool level)
129 {
130     digitalWrite(PIN_CLOCK, level);
131 }
132 
133 //  D[7:0]  -------------------------
134 //  CLK     ^^^^^^\___/^^^^\____/^^^^
135 //  nIOREQ  ^^^\_________________/^^^
136 //  nCS     ^^^\_________________/^^^
137 //  nRD     ^^^\_________________/^^^
138 //  nWR     ^^^^^^^^^^^^^^^^^^^^^^^^^
139 //  read                   *
140 //  Reads when drive goes high (*)
141 void MCUBus::PulseIORD()
142 {
143     Clock(LOW);
144     UpdateChip(0xe); // RD
145     IOReqLine(LOW);
146     SUPER_SLO_MO();
147 
148     Clock(HIGH);
149     UpdateChip(0x6); // drive, RD
150     SUPER_SLO_MO();
151 
152     Clock(LOW);
153     UpdateChip(0xe); // RD
154     SUPER_SLO_MO();
155 
156     Clock(HIGH);
157     SUPER_SLO_MO();
158 
159     Clock(LOW);
160     IOReqLine(HIGH);
161     UpdateChip(0xf); // done
162     SUPER_SLO_MO();
163 
164     Clock(HIGH);
165     SUPER_SLO_MO();
166 
167 }
168 //  D[7:0]  -[                     ]-
169 //  CLK     ^^^^^^\___/^^^^\____/^^^^
170 //  nIOREQ  ^^^\_________________/^^^
171 //  nCS     ^^^\_________________/^^^
172 //  nRD     ^^^^^^^^^^^^^^^^^^^^^^^^^
173 //  nWR     ^^^^^^^\_________/^^^^^^^
174 //  Writes when nWR goes low
175 void MCUBus::PulseIOWR()
176 {
177     Clock(LOW);
178     UpdateChip(0x7); // drive
179     IOReqLine(LOW);
180     SUPER_SLO_MO();
181 
182     Clock(HIGH);
183     UpdateChip(0x5); // drive, WR
184     SUPER_SLO_MO();
185 
186     Clock(LOW);
187     UpdateChip(0x7); // drive
188     UpdateChip(0xf); // done
189     SUPER_SLO_MO();
190 
191     Clock(HIGH);
192     SUPER_SLO_MO();
193 
194     Clock(LOW);
195     IOReqLine(HIGH);
196     SUPER_SLO_MO();
197 
198     Clock(HIGH);
199     SUPER_SLO_MO();
200 
201 }
202 
203 //  D[7:0]  -------------------------
204 //  CLK     ^^^^^^\___/^^^^\____/^^^^
205 //  nMREQ   ^^^\_________________/^^^
206 //  nM1     ^^^\_________________/^^^
207 //  nCS     ^^^\_________________/^^^
208 //  nRD     ^^^\_________________/^^^
209 //  nWR     ^^^^^^^^^^^^^^^^^^^^^^^^^
210 //  read                   *
211 //  Reads when drive goes high (*)
212 void MCUBus::PulseFetch()
213 {
214     Clock(LOW);
215     M1Line(LOW);
216     UpdateChip(0xe); // RD
217     MemReqLine(LOW);
218     SUPER_SLO_MO();
219 
220     Clock(HIGH);
221     UpdateChip(0x6); // drive, RD
222     SUPER_SLO_MO();
223 
224     Clock(LOW);
225     UpdateChip(0xe); // RD
226     M1Line(HIGH);
227     SUPER_SLO_MO();
228 
229     Clock(HIGH);
230     SUPER_SLO_MO();
231 
232     Clock(LOW);
233     MemReqLine(HIGH);
234     UpdateChip(0xf); // done
235     SUPER_SLO_MO();
236 
237     Clock(HIGH);
238     SUPER_SLO_MO();
239 
240 }
241 
242 //  D[7:0]  -------------------------
243 //  CLK     ^^^^^^\___/^^^^\____/^^^^
244 //  nMREQ   ^^^\_________________/^^^
245 //  nM1     ^^^^^^^^^^^^^^^^^^^^^^^^^
246 //  nCS     ^^^\_________________/^^^
247 //  nRD     ^^^\_________________/^^^
248 //  nWR     ^^^^^^^^^^^^^^^^^^^^^^^^^
249 //  read                   *
250 //  Reads when drive goes high (*)
251 void MCUBus::PulseMemRD()
252 {
253     Clock(LOW);
254     UpdateChip(0xe); // RD
255     MemReqLine(LOW);
256     SUPER_SLO_MO();
257 
258     Clock(HIGH);
259     UpdateChip(0x6); // drive, RD
260     SUPER_SLO_MO();
261 
262     Clock(LOW);
263     UpdateChip(0xe); // RD
264     SUPER_SLO_MO();
265 
266     Clock(HIGH);
267     SUPER_SLO_MO();
268 
269     Clock(LOW);
270     MemReqLine(HIGH);
271     UpdateChip(0xf); // done
272     SUPER_SLO_MO();
273 
274     Clock(HIGH);
275     SUPER_SLO_MO();
276 
277 }
278 
279 //  D[7:0]  -[                     ]-
280 //  CLK     ^^^^^^\___/^^^^\____/^^^^
281 //  nMREQ   ^^^\_________________/^^^
282 //  nCS     ^^^\_________________/^^^
283 //  nRD     ^^^^^^^^^^^^^^^^^^^^^^^^^
284 //  nWR     ^^^^^^^\_________/^^^^^^^
285 //  Writes when nWR goes low
286 void MCUBus::PulseMemWR()
287 {
288     Clock(LOW);
289     UpdateChip(0x7); // drive
290     MemReqLine(LOW);
291     SUPER_SLO_MO();
292 
293     Clock(HIGH);
294     UpdateChip(0x5); // drive, WR
295     SUPER_SLO_MO();
296 
297     Clock(LOW);
298     UpdateChip(0x7); // drive
299     UpdateChip(0xf); // done
300     SUPER_SLO_MO();
301 
302     Clock(HIGH);
303     SUPER_SLO_MO();
304 
305     Clock(LOW);
306     MemReqLine(HIGH);
307     SUPER_SLO_MO();
308 
309     Clock(HIGH);
310     SUPER_SLO_MO();
311 
312 }

Exchanger.h

 1 #ifndef INCLUDED_EXCHANGER_H
 2 #define INCLUDED_EXCHANGER_H
 3 
 4 #include <arduino.h>
 5 #include "SerialIF.h"
 6 
 7 // The exchanger handles communication between the PC and the Arduino
 8 class Exchanger {
 9 public:
10     Exchanger();
11     ~Exchanger();
12 
13     // Expect a command. User supplied buffer. It provides the actual length received. Returns true on success
14     bool WaitForCommand(uint8_t* receiveBuffer256, int* pLengthReceived);
15 
16     // Send a response in sendBuffer256. 'lengthToSend' is 1-255 and 0 means 256
17     bool SendResponse(const uint8_t* sendBuffer256, uint8_t lengthToSend);
18 
19     // Sends a payload part. packetId is sequential from 0. lengthToSend is 1-255 and 0 means 256
20     bool SendPayload(uint16_t packetId, const uint8_t* sendBuffer256, uint8_t lengthToSend);
21 
22     // Waits for a payload part. pLengthReceived is 1-255 and 0 means 256
23     bool WaitForPayload(uint16_t expectedPacketId, uint8_t* receiveBuffer256, uint8_t* pLengthReceived);
24 
25     // Sends a ready to indicate ready for the next payload part
26     bool SendReady(uint16_t packetId);
27 
28     // Waits for ready to send next packet. buffer is a buffer that can be destroyed
29     bool WaitForReady(uint16_t packetId, uint8_t* buffer);
30 
31     // Sends a text string (up to but not including the NUL terminator)
32     bool SendText(const char* text);
33 
34 private:
35     SerialIF m_serial;
36     byte m_id;
37 };
38 
39 #endif

Exchanger.cpp

 1 #include "Exchanger.h"
 2 
 3 Exchanger::Exchanger() : m_serial()
 4 {
 5 }
 6 
 7 Exchanger::~Exchanger()
 8 {
 9 }
10 
11 ///////////////////////////////////////////////////////////////////////////////
12 //
13 //      PC -> Arduiono Receive section
14 //
15 
16 bool Exchanger::WaitForCommand(uint8_t* receiveBuffer256, int* pLengthReceived)
17 {
18     bool ok = false;
19     char c;
20     uint16_t packetId;
21     uint16_t length = m_serial.Receive(&c, receiveBuffer256, &m_id, &packetId);
22     if ((c == '>') & (length > 0))
23     {
24         *pLengthReceived = length;
25         ok = true;
26     }
27     return ok;
28 }
29 
30 bool Exchanger::WaitForReady(uint16_t expectedPacketId, uint8_t* buffer)
31 {
32     bool ok = false;
33     char c;
34     uint16_t packetId;
35     int recv = m_serial.Receive(&c, buffer, &m_id, &packetId);
36     if (c == '.' && packetId == expectedPacketId && recv == 1)
37     {
38         ok = true;
39     }
40     return ok;
41 }
42 
43 
44 bool Exchanger::WaitForPayload(uint16_t expectedPacketId, uint8_t* receiveBuffer256, uint8_t* pLengthReceived)
45 {
46     bool ok = false;
47     char c;
48     uint16_t packetId;
49     uint16_t length = m_serial.Receive(&c, receiveBuffer256, &m_id, &packetId);
50     if (c == '$' && length > 0 && packetId == expectedPacketId)
51     {
52         *pLengthReceived = length;
53         ok = true;
54     }
55     return ok;
56 }
57 
58 
59 ///////////////////////////////////////////////////////////////////////////////
60 //
61 //      Arduoino -> PC section
62 //
63 
64 bool Exchanger::SendResponse(const uint8_t* sendBuffer256, uint8_t lengthToSend)
65 {
66     return m_serial.Send('<', sendBuffer256, lengthToSend, m_id, 0);
67 }
68 
69 bool Exchanger::SendReady(uint16_t packetId)
70 {
71     uint8_t buffer[1];
72     return m_serial.Send('.', buffer, 1, m_id, packetId);
73 }
74 
75 bool Exchanger::SendPayload(uint16_t packetId, const uint8_t* sendBuffer256, uint8_t lengthToSend)
76 {
77     int length = lengthToSend;
78     if (length == 0)
79     {
80         length = 256;
81     }
82     bool ok = m_serial.Send('$', sendBuffer256, length, m_id, packetId);
83     return ok;
84 }
85 
86 bool Exchanger::SendText(const char* text)
87 {
88     int16_t length = strlen(text);
89     bool ok = m_serial.Send('!', (uint8_t*)text, length, m_id, 0xdead);
90     return ok;
91 }

Interpreter.h

 1 #ifndef INCLUDE_INTERPRETER_H
 2 #define INCLUDE_INTERPRETER_H
 3 #include <stdint.h>
 4 #include "MCUBus.h"
 5 #include "Flash.h"
 6 #include "SerialIF.h"
 7 #include "Exchanger.h"
 8 
 9 class Interpreter
10 {
11 public:
12     Interpreter();
13     ~Interpreter();
14 
15     // Run the interpreter
16     void Loop();
17 
18     // Execute a command
19     bool Execute(const uint8_t* command, int commmandLength, uint8_t* pResponse, int* pResponseLength);
20 
21     // Send a diag message up to 100 chars
22     static void DiagnosticText(const char* format, ...);
23 
24 protected:
25     bool CRC(uint32_t addr, uint32_t length, uint32_t* pCRC);
26     uint32_t IncrementalCRC(uint32_t crc, uint8_t data);
27 
28 private:
29     static Interpreter* m_instance;
30 
31     uint16_t m_configuration;
32     uint16_t m_status;
33 
34     MCUBus m_bus;
35     SerialIF m_serialIF;
36     Flash m_fp;
37     Exchanger m_exch;
38     uint8_t m_id; // rotating transaction ID
39 };
40 
41 #endif

Interpreter.cpp

  1 #include <arduino.h>
  2 #include <string.h>
  3 #include "Interpreter.h"
  4 #include "Exchanger.h"
  5 #include "Flash.h"
  6 #include "CRC32.h"
  7 #include "CommandCodeEnum.h"
  8 #include "Commands.h"
  9 #include "Responses.h"
 10 
 11 #define BLINK_ON_SUCCESS 0
 12 #define BLINK_ON_FAILURE 0
 13 #define VERBOSE 1
 14 
 15 ///////////////////////////////////////////////////////////////////////////////
 16 //
 17 //      Object section
 18 //
 19 
 20 Interpreter::Interpreter() : m_fp(m_bus)
 21 {
 22     m_status = 0;
 23     m_configuration = 0;
 24     m_instance = this;
 25 }
 26 
 27 Interpreter::~Interpreter()
 28 {
 29 }
 30 
 31 Interpreter* Interpreter::m_instance;
 32 
 33 void Interpreter::Loop()
 34 {
 35     uint8_t command[256];
 36     uint8_t response[256];
 37     while (1)
 38     {
 39         int receivedLength;
 40         int responseLength;
 41         if (m_exch.WaitForCommand(command, &receivedLength) > 0)
 42         {
 43             m_fp.Reset();
 44 
 45             bool ok = Execute(command, receivedLength, response, &responseLength);
 46 
 47             if (ok)
 48             {
 49                 m_exch.SendResponse(response, responseLength);
 50                 if (BLINK_ON_SUCCESS)
 51                 {
 52                     // half second beep bo beep
 53                     digitalWrite(13, HIGH);
 54                     delay(200);
 55                     digitalWrite(13, LOW);
 56                     delay(100);
 57                     digitalWrite(13, HIGH);
 58                     delay(200);
 59                     digitalWrite(13, LOW);
 60                 }
 61             }
 62             else
 63             {
 64                 response[0] = '?';
 65                 response[1] = 0xde;
 66                 response[2] = 0xad;
 67                 response[3] = 0xbe;
 68                 response[4] = 0xef;
 69                 m_exch.SendResponse(response, 5);
 70                 if (BLINK_ON_FAILURE)
 71                 {
 72                     // flutter LED
 73                     for (int16_t i = 0; i < 10; ++i)
 74                     {
 75                         digitalWrite(13, HIGH);
 76                         delay(50);
 77                         digitalWrite(13, LOW);
 78                         delay(50);
 79                     }
 80                 }
 81             }
 82         }
 83     }
 84 }
 85 
 86 void Interpreter::DiagnosticText(const char* format, ...)
 87 {
 88 #define DIAGNOSTIC_TEXT_SIZE 100
 89     char text[DIAGNOSTIC_TEXT_SIZE];
 90     va_list ap;
 91     va_start(ap, format);
 92     vsnprintf(text, DIAGNOSTIC_TEXT_SIZE, format, ap);
 93     va_end(ap);
 94     m_instance->m_exch.SendText(text);
 95 }
 96 
 97 ///////////////////////////////////////////////////////////////////////////////
 98 //
 99 //      Command Dispatch section
100 //
101 
102 bool Interpreter::Execute(const uint8_t* command, int commmandLength, uint8_t* pResponse, int* pResponseLength)
103 {
104     bool ok = false;
105 
106     switch (command[0])
107     {
108     case NOP:
109     {
110         CmdNOP cmd(command, commmandLength);
111         ok = true;
112         RespNOP resp(cmd, pResponse);
113         resp.SetResult(ok);
114         *pResponseLength = resp.Length();
115     }
116     break;
117     case Status:
118     {
119         CmdStatus cmd(command, commmandLength);
120         ok = true;
121 
122         RespStatus resp(cmd, pResponse);
123         uint32_t status = m_configuration;
124         status <<= 16;
125         status |= m_status;
126         resp.SetStatus(status);
127         resp.SetResult(ok);
128         *pResponseLength = resp.Length();
129     }
130     break;
131     case Configure:
132     {
133         CmdConfigure cmd(command, commmandLength);
134         ok = true;
135         m_configuration = (uint16_t)cmd.GetConfig();
136         RespConfigure resp(cmd, pResponse);
137         resp.SetResult(resp.Length());
138         *pResponseLength = resp.Length();
139     }
140     break;
141     case ForceReset:
142     {
143         CmdForceReset cmd(command, commmandLength);
144         ok = m_fp.ForceReset();
145         RespForceReset resp(cmd, pResponse);
146         resp.SetResult(ok);
147         *pResponseLength = resp.Length();
148     }
149     break;
150     case EnablePins:
151     {
152         CmdEnablePins cmd(command, commmandLength);
153         bool enable = cmd.GetEnable();
154         ok = m_bus.EnablePins(enable);
155         RespEnablePins resp(cmd, pResponse);
156         resp.SetResult(ok);
157         *pResponseLength = resp.Length();
158     }
159     break;
160 
161     case ReadByte:
162     {
163         CmdReadByte cmd(command, commmandLength);
164         uint8_t data;
165         ok = m_fp.Read(cmd.GetAddress(), &data);
166         RespReadByte resp(cmd, pResponse);
167         resp.SetData(data);
168         resp.SetResult(ok);
169         *pResponseLength = resp.Length();
170     }
171     break;
172     case WriteByte:
173     {
174         CmdWriteByte cmd(command, commmandLength);
175         m_bus.Write(cmd.GetAddress(), cmd.GetData());
176         ok = true;
177     case WriteByte:
178     {
179         CmdWriteByte cmd(command, commmandLength);
180         m_bus.Write(cmd.GetAddress(), cmd.GetData());
181         ok = true;
182         //DiagnosticText("Write byte %05lx <- %02x", cmd.GetAddress(), cmd.GetData());
183         RespWriteByte resp(cmd, pResponse);
184         resp.SetResult(ok);
185         *pResponseLength = resp.Length();
186     }
187     break;
188     case ProgramByte:
189     {
190         CmdProgramByte cmd(command, commmandLength);
191         ok = m_fp.Program(cmd.GetAddress(), cmd.GetData());
192         RespProgramByte resp(cmd, pResponse);
193         resp.SetResult(ok);
194         *pResponseLength = resp.Length();
195     }
196     break;
197 
198     case ReadBlock:
199     {
200         CmdReadBlock cmd(command, commmandLength);
201         uint32_t addr = cmd.GetAddress();
202         uint32_t length = cmd.GetLength();
203         uint32_t offset = 0;
204         uint16_t packetId = 0;
205         ok = true;
206 
207         while (offset < length && ok)
208         {
209             if (ok)
210             {
211                 // wait for ready to send
212                 ok = ok && m_exch.WaitForReady(packetId, pResponse);
213 
214                 // load packet
215                 int32_t partLen = length - offset;
216                 if (partLen > 256)
217                 {
218                     partLen = 256;
219                 }
220                 for (int i = 0; i < partLen; ++i)
221                 {
222                     uint8_t b;
223                     ok = ok && m_fp.Read(addr + offset + i, &b);
224                     b = (byte)(addr + offset + i);
225                     pResponse[i] = b;
226                 }
227 
228                 // send it out
229                 ok = ok && m_exch.SendPayload(packetId, pResponse, partLen);
230 
231                 // prepare for next packet
232                 offset += partLen;
233                 packetId++;
234             }
235         }
236         RespReadBlock resp(cmd, pResponse);
237         resp.SetResult(ok);
238         *pResponseLength = resp.Length();
239     }
240     break;
241     case ProgramBlock:
242     {
243         CmdReadBlock cmd(command, commmandLength);
244         uint32_t addr = cmd.GetAddress();
245         uint32_t length = cmd.GetLength();
246         uint32_t offset = 0;
247         uint16_t packetId = 0;
248         uint8_t buffer[256];
249         ok = true;
250         while (offset < length)
251         {
252             if (ok)
253             {
254                 uint8_t partLen;
255                 ok = ok && m_exch.SendReady(packetId);
256                 ok = ok && m_exch.WaitForPayload(packetId, buffer, &partLen);
257                 int len = partLen;
258                 if (len == 0)
259                 {
260                     len = 256;
261                 }
262 
263                 // program packet
264                 for (int i = 0; i < len; ++i)
265                 {
266                     uint8_t b = buffer[i];
267                     ok = ok && m_fp.Program(addr + offset + i, b);
268                 }
269 
270                 // prepare for next packet
271                 offset += len;
272                 packetId++;
273             }
274         }
275         RespReadBlock resp(cmd, pResponse);
276         resp.SetResult(ok);
277         *pResponseLength = resp.Length();
278     }
279     break;
280 
281     case EraseSector:
282     {
283         CmdEraseSector cmd(command, commmandLength);
284         int sector = cmd.GetSector();
285         int count = cmd.GetCount();
286         ok = sector >= 0 && sector < 64 && count >= 1 && (sector + count) < 64;
287         for (int i = sector; i < sector + count; ++i)
288         {
289             if (ok)
290             {
291                 ok = m_fp.EraseSector(sector << 12);
292             }
293         }
294         RespEraseSector resp(cmd, pResponse);
295         resp.SetResult(ok);
296         *pResponseLength = resp.Length();
297     }
298     break;
299     case EraseChip:
300     {
301         CmdEraseChip cmd(command, commmandLength);
302         ok = m_fp.EraseChip();
303         RespEraseChip resp(cmd, pResponse);
304         resp.SetResult(ok);
305         *pResponseLength = resp.Length();
306     }
307     break;
308 
309     case VerifyErase:
310     {
311         CmdVerifyErase cmd(command, commmandLength);
312         uint8_t data;
313         uint32_t errorCount = 0;
314         uint32_t addr = cmd.GetAddress();
315         uint32_t length = cmd.GetLength();
316         ok = true;
317         for (uint32_t i = 0; i < length; i++)
318         {
319             ok = ok && m_fp.Read(addr + i, &data);
320             if (data != 0xff)
321             {
322                 //DiagnosticText("Error %d at %x", data, addr + i);
323                 errorCount++;
324             }
325         }
326         RespVerifyErase resp(cmd, pResponse);
327         resp.SetErrorCount(errorCount);
328         resp.SetResult(ok);
329         *pResponseLength = resp.Length();
330     }
331     break;
332 
333     case BlockCRC:
334     {
335         CmdBlockCRC cmd(command, commmandLength);
336         uint8_t data;
337         uint32_t addr = cmd.GetAddress();
338         uint32_t length = cmd.GetLength();
339         uint32_t crc = 0xffffffffUL;
340         ok = true;
341         for (uint32_t i = 0; i < length; i++)
342         {
343             ok = ok && m_fp.Read(addr + length, &data);
344             data = 0xff; // TODO remove after test
345             crc = CRC32::IncrementalCRC(crc, data);
346         }
347         RespBlockCRC resp(cmd, pResponse);
348         resp.SetCRC(crc ^ 0xffffffffUL);
349         resp.SetResult(ok);
350         *pResponseLength = resp.Length();
351     }
352     break;
353 
354     case DirectPinRead:
355     {
356         CmdDirectPinRead cmd(command, commmandLength);
357         uint16_t levels;
358         ok = m_bus.DirectRead(cmd.GetMask(), &levels);
359         RespDirectPinRead resp(cmd, pResponse);
360         resp.SetPins(levels);
361         resp.SetResult(ok);
362         *pResponseLength = resp.Length();
363     }
364     break;
365     case DirectPinWrite:
366     {
367         CmdDirectPinWrite cmd(command, commmandLength);
368         ok = m_bus.DirectWrite(cmd.GetMask(), cmd.GetLevels());
369         RespDirectPinWrite resp(cmd, pResponse);
370         resp.SetResult(ok);
371         *pResponseLength = resp.Length();
372     }
373     break;
374     case DirectPinMode:
375     {
376         CmdDirectPinMode cmd(command, commmandLength);
377         uint8_t pin = cmd.GetPin();
378         uint8_t mode = cmd.GetMode();
379         ok = pin < 14 && (mode == INPUT || mode == INPUT_PULLUP || mode == OUTPUT);
380         if (ok)
381         {
382             pinMode(pin, mode);
383         }
384         RespDirectPinMode resp(cmd, pResponse);
385         resp.SetResult(ok);
386         *pResponseLength = resp.Length();
387     }
388     break;
389 
390     case ReadMem:
391     {
392         CmdReadMem cmd(command, commmandLength);
393         uint8_t data;
394         ok = m_bus.ReadMem(cmd.GetAddress(), &data);
395         RespReadMem resp(cmd, pResponse);
396         resp.SetData(data);
397         resp.SetResult(ok);
398         *pResponseLength = resp.Length();
399     }
400     break;
401     case FetchMem:
402     {
403         CmdFetchMem cmd(command, commmandLength);
404         uint8_t data;
405         ok = m_bus.FetchMem(cmd.GetAddress(), &data);
406         RespFetchMem resp(cmd, pResponse);
407         resp.SetData(data);
408         resp.SetResult(ok);
409         *pResponseLength = resp.Length();
410     }
411     break;
412     case WriteMem:
413     {
414         CmdWriteMem cmd(command, commmandLength);
415         ok = m_bus.WriteMem(cmd.GetAddress(), cmd.GetData());
416         RespWriteMem resp(cmd, pResponse);
417         resp.SetResult(ok);
418         *pResponseLength = resp.Length();
419     }
420     break;
421     case ReadPort:
422     {
423         CmdReadPort cmd(command, commmandLength);
424         uint8_t data;
425         ok = m_bus.ReadIO(cmd.GetPort(), &data);
426         RespReadPort resp(cmd, pResponse);
427         resp.SetData(data);
428         resp.SetResult(ok);
429         *pResponseLength = resp.Length();
430     }
431     break;
432     case WritePort:
433     {
434         CmdWritePort cmd(command, commmandLength);
435         ok = m_bus.WriteIO(cmd.GetPort(), cmd.GetData());
436         RespWritePort resp(cmd, pResponse);
437         resp.SetResult(ok);
438         *pResponseLength = resp.Length();
439     }
440     break;
441     }
442     return ok;
443 }
444 
445 
446 <!----->
447 </string>
448 </arduino>

ArgInfo.h

 1 #ifndef INCLUDED_ARGINFO_H
 2 #define INCLUDED_ARGINFO_H
 3 #include <arduino.h>
 4 #include "CommandCodeEnum.h"
 5 
 6 struct ArgTypes
 7 {
 8     CommandCodes code;
 9     const char* name;
10     int location;
11     int length;
12 };
13 
14 // The ArgInfo class contains the information needed for commands and responses to location
15 // and extract the information in the communication packets
16 class ArgInfo
17 {
18 public:
19     ArgInfo();
20     ~ArgInfo();
21 
22     // Gets data from a command
23     bool CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, uint32_t* pData);
24     bool CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, uint16_t* pData);
25     bool CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, uint8_t* pData);
26     bool CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, int* pData);
27     bool CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, bool* pData);
28 
29     // Inserts data into a response
30     bool ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, uint32_t data);
31     bool ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, uint16_t data);
32     bool ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, uint8_t data);
33     bool ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, int data);
34     bool ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, bool data);
35 
36     // Gets the total length of the command
37     int CommandLength(CommandCodes code);
38 
39     // Gets the total length of the response which is the length of the command, the status, and arguments
40     int ResponseLength(CommandCodes code);
41 
42 protected:
43     // Gets the location and length of argument #'argNo' for command of 'commandCode'
44     bool GetCommandInfo(CommandCodes code, int argNo, int* pLocation, int* pLength);
45 
46     // Gets the location and length of argument #'argNo' for response of 'commandCode'
47     bool GetResponseInfo(CommandCodes code, int argNo, int* pLocation, int* pLength);
48 
49     // Gets the actual data at 'location'
50     bool ExtractFrom(const uint8_t* buffer, int location, int length, uint32_t* pData);
51 
52     // Inserts the actual data at 'location'
53     bool InsertInto(uint8_t* buffer, int location, int length, uint32_t data);
54 
55     // Number of ArgTypes in COMMAND_ARGS
56     static int COMMAND_ARGC;
57 
58     // Number of ArgTypes in RESPONSE_ARGS
59     static int RESPONSE_ARGC;
60 
61     // Array of info about command arguments
62     static ArgTypes COMMAND_ARGS[];
63 
64     // Array of info abaout response arguments
65     static ArgTypes RESPONSE_ARGS[];
66 };
67 
68 #endif
69 
70 </arduino>

ArgInfo.cpp

  1 #include "ArgInfo.h"
  2 
  3 
  4 #include "Interpreter.h" // TODO for diag
  5 
  6 // locations start at 0. THey will be set in the c'tor
  7 ArgTypes ArgInfo::COMMAND_ARGS[] =
  8 {
  9     { Configure, "Configure", 0, 2 },
 10 
 11     { ReadByte, "Address", 0, 3 },
 12 
 13     { WriteByte, "Address", 0, 3 },
 14     { WriteByte, "Data", 0, 1 },
 15 
 16     { ProgramByte, "Address", 0, 3},
 17     { ProgramByte, "Data", 0, 1},
 18 
 19     { ReadBlock, "Address", 0, 3},
 20     { ReadBlock, "Length", 0, 3},
 21 
 22     { ProgramBlock, "Address", 0, 3},
 23     { ProgramBlock, "Length", 0, 3},
 24 
 25     { EraseSector, "Sector", 0, 1},
 26     { EraseSector, "Count", 0, 1},
 27 
 28     { VerifyErase, "Address", 0, 3},
 29     { VerifyErase, "Length", 0, 3},
 30 
 31     { BlockCRC, "Address", 0, 3},
 32     { BlockCRC, "Length", 0, 3},
 33 
 34     { EnablePins, "Pin", 0, 1},
 35     { EnablePins, "Mode", 0, 1},
 36 
 37     { DirectPinWrite, "Mask", 0, 2},
 38     { DirectPinWrite, "Levels", 0, 2},
 39 
 40     { DirectPinRead, "Mask", 0, 2},
 41 
 42     { ReadMem, "Address", 0, 2},
 43 
 44     { FetchMem, "Address", 0, 2},
 45 
 46     { WriteMem, "Address", 0, 2},
 47     { WriteMem, "Data", 0, 1},
 48 
 49     { ReadPort, "Port", 0, 1},
 50 
 51     { WritePort, "Port", 0, 1},
 52     { WritePort, "Data", 0, 1},
 53 };
 54 
 55 // locations all default to 1. These may not be set in the c'tor
 56 ArgTypes ArgInfo::RESPONSE_ARGS[] =
 57 {
 58     { ReadByte, "Data", 1, 1 },
 59     { ReadMem, "Data", 1, 1 },
 60     { FetchMem, "Data", 1, 1 },
 61     { ReadPort, "Data", 1, 1 },
 62 
 63     { Status, "Status", 1, 4 },
 64 
 65     { VerifyErase, "ErrorCount", 1, 4 },
 66 
 67     { BlockCRC, "CRC", 1, 4 },
 68 
 69     { DirectPinRead, "Levels", 1, 2 },
 70 };
 71 
 72 // Gets sizes at compile time
 73 int ArgInfo::COMMAND_ARGC = sizeof(COMMAND_ARGS) / sizeof(COMMAND_ARGS[0]);
 74 int ArgInfo::RESPONSE_ARGC = sizeof(RESPONSE_ARGS) / sizeof(RESPONSE_ARGS[0]);
 75 
 76 ArgInfo::ArgInfo()
 77 {
 78     // Figure out locations from sizes
 79     CommandCodes lastCommandCode = (CommandCodes)-1;
 80     int cumulativeLocation = 1;
 81     for (int i = 0; i < COMMAND_ARGC; ++i)
 82     {
 83         if (COMMAND_ARGS[i].code != lastCommandCode)
 84         {
 85             // add into response
 86             for (int j = 0; j < RESPONSE_ARGC; ++j)
 87             {
 88                 if (RESPONSE_ARGS[j].code == lastCommandCode)
 89                 {
 90                     RESPONSE_ARGS[j].location = cumulativeLocation;
 91                     cumulativeLocation += RESPONSE_ARGS[j].length;
 92                 }
 93             }
 94 
 95             lastCommandCode = COMMAND_ARGS[i].code;
 96             cumulativeLocation = 1;
 97         }
 98         COMMAND_ARGS[i].location = cumulativeLocation;
 99         cumulativeLocation += COMMAND_ARGS[i].length;
100     }
101 }
102 
103 ArgInfo::~ArgInfo()
104 {
105 }
106 
107 int ArgInfo::CommandLength(CommandCodes code)
108 {
109     int cumulativeLength = 1;
110     for (int i = 0; i < COMMAND_ARGC; ++i)
111     {
112         CommandCodes thisCommandCode = COMMAND_ARGS[i].code;
113 
114         if (thisCommandCode < code)
115         {
116         }
117         else if (thisCommandCode == code)
118         {
119             cumulativeLength += COMMAND_ARGS[i].length;
120         }
121         else
122         {
123             //break; // not in order--cannot break
124         }
125     }
126     return cumulativeLength;
127 }
128 
129 int ArgInfo::ResponseLength(CommandCodes code)
130 {
131     int cumulativeLength = CommandLength(code) + 1; // +1 for result
132     for (int i = 0; i < RESPONSE_ARGC; ++i)
133     {
134         CommandCodes thisCommandCode = RESPONSE_ARGS[i].code;
135 
136         if (thisCommandCode < code)
137         {
138         }
139         else if (thisCommandCode == code)
140         {
141             cumulativeLength += RESPONSE_ARGS[i].length;
142         }
143         else
144         {
145             //break; // not in order--cannot break
146         }
147     }
148     return cumulativeLength;
149 }
150 
151 
152 bool ArgInfo::CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, uint32_t* pData)
153 {
154     int location;
155     int length;
156     uint32_t data32 = 0;
157 
158     bool ok = GetCommandInfo(code, argNo, &location, &length);
159 
160     if (ok)
161     {
162         ok = ExtractFrom(buffer, location, length, &data32);
163     }
164     if (ok)
165     {
166         *pData = (uint32_t)data32;
167     }
168 
169     return ok;
170 }
171 
172 bool ArgInfo::CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, uint16_t* pData)
173 {
174     int location;
175     int length;
176     uint32_t data32 = 0;
177 
178     bool ok = GetCommandInfo(code, argNo, &location, &length);
179 
180     if (ok)
181     {
182         ok = ExtractFrom(buffer, location, length, &data32);
183     }
184     if (ok)
185     {
186         *pData = (uint16_t)data32;
187     }
188 
189     return ok;
190 }
191 
192 bool ArgInfo::CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, uint8_t* pData)
193 {
194     int location;
195     int length;
196     uint32_t data32 = 0;
197 
198     bool ok = GetCommandInfo(code, argNo, &location, &length);
199 
200     if (ok)
201     {
202         ok = ExtractFrom(buffer, location, length, &data32);
203     }
204     if (ok)
205     {
206         *pData = (uint8_t)data32;
207     }
208 
209     return ok;
210 }
211 
212 bool ArgInfo::CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, int* pData)
213 {
214     int location;
215     int length;
216     uint32_t data32 = 0;
217 
218     bool ok = GetCommandInfo(code, argNo, &location, &length);
219 
220     if (ok)
221     {
222         ok = ExtractFrom(buffer, location, length, &data32);
223     }
224     if (ok)
225     {
226         *pData = (int)data32;
227     }
228 
229     return ok;
230 }
231 
232 bool ArgInfo::CommandExtract(CommandCodes code, int argNo, const uint8_t* buffer, bool* pData)
233 {
234     int location;
235     int length;
236     uint32_t data32 = 0;
237 
238     bool ok = GetCommandInfo(code, argNo, &location, &length);
239 
240     if (ok)
241     {
242         ok = ExtractFrom(buffer, location, length, &data32);
243     }
244     if (ok)
245     {
246         *pData = data32 != 0;
247     }
248 
249     return ok;
250 }
251 
252 
253 bool ArgInfo::ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, uint32_t data)
254 {
255     int location;
256     int length;
257     uint32_t data32 = data;
258 
259     bool ok = GetResponseInfo(code, argNo, &location, &length);
260     if (ok)
261     {
262         ok = InsertInto(buffer, location, length, data32);
263     }
264     return ok;
265 }
266 
267 bool ArgInfo::ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, uint16_t data)
268 {
269     int location;
270     int length;
271     uint32_t data32 = data;
272 
273     bool ok = GetResponseInfo(code, argNo, &location, &length);
274     if (ok)
275     {
276         ok = InsertInto(buffer, location, length, data32);
277     }
278     return ok;
279 }
280 
281 bool ArgInfo::ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, uint8_t data)
282 {
283     int location;
284     int length;
285     uint32_t data32 = data;
286 
287     bool ok = GetResponseInfo(code, argNo, &location, &length);
288     if (ok)
289     {
290         ok = InsertInto(buffer, location, length, data32);
291     }
292     return ok;
293 }
294 
295 bool ArgInfo::ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, int data)
296 {
297     int location;
298     int length;
299     uint32_t data32 = data;
300 
301     bool ok = GetResponseInfo(code, argNo, &location, &length);
302     if (ok)
303     {
304         ok = InsertInto(buffer, location, length, data32);
305     }
306     return ok;
307 }
308 
309 bool ArgInfo::ResponseInsert(CommandCodes code, int argNo, uint8_t* buffer, bool data)
310 {
311     int location;
312     int length;
313     uint32_t data32 = data;
314 
315     bool ok = GetResponseInfo(code, argNo, &location, &length);
316     if (ok)
317     {
318         ok = InsertInto(buffer, location, length, data32 ? 1 : 0);
319     }
320     return ok;
321 }
322 
323 bool ArgInfo::GetCommandInfo(CommandCodes code, int argNo, int* pLocation, int* pLength)
324 {
325     int i = 0;
326     while (i < COMMAND_ARGC && COMMAND_ARGS[i].code != code)
327     {
328         ++i;
329     }
330     if (i == COMMAND_ARGC)
331     {
332         return false;
333     }
334     int argC = 0;
335     while (i < COMMAND_ARGC && COMMAND_ARGS[i].code == code && argC < argNo)
336     {
337         ++i;
338         ++argC;
339     }
340     if (i == COMMAND_ARGC || COMMAND_ARGS[i].code != code)
341     {
342         return false;
343     }
344     *pLocation = COMMAND_ARGS[i].location;
345     *pLength = COMMAND_ARGS[i].length;
346     return true;
347 }
348 
349 bool ArgInfo::GetResponseInfo(CommandCodes code, int argNo, int* pLocation, int* pLength)
350 {
351     int i = 0;
352     while (i < RESPONSE_ARGC && RESPONSE_ARGS[i].code != code)
353     {
354         ++i;
355     }
356     if (i == RESPONSE_ARGC)
357     {
358         return false;
359     }
360     int argC = 0;
361     while (i < RESPONSE_ARGC && RESPONSE_ARGS[i].code == code && argC < argNo)
362     {
363         ++i;
364         ++argC;
365     }
366     if (i == RESPONSE_ARGC || RESPONSE_ARGS[i].code != code)
367     {
368         return false;
369     }
370     *pLocation = RESPONSE_ARGS[i].location;
371     *pLength = RESPONSE_ARGS[i].length;
372     return true;
373 }
374 
375 bool ArgInfo::ExtractFrom(const uint8_t* buffer, int location, int length, uint32_t* pData)
376 {
377     bool ok = length <= 4 && location >= 0 && location < 256;
378 
379     if (ok)
380     {
381         uint32_t data = 0;
382         for (int i = location; i < location + length; ++i)
383         {
384             data <<= 8;
385             data |= buffer[i];
386         }
387         *pData = data;
388     }
389     return ok;
390 }
391 
392 bool ArgInfo::InsertInto(uint8_t* buffer, int location, int length, uint32_t data)
393 {
394     bool ok = length <= 4 && location >= 0 && (location+length) < 256;
395 
396     if (ok)
397     {
398         for (int i = location + length - 1; i >= location; --i)
399         {
400             buffer[i] = (uint8_t)data;
401             data >>= 8;
402         }
403     }
404     return ok;
405 }

Commands.h

  1 #ifndef INCLUDED_COMMANDS_H
  2 #define INCLUDED_COMMANDS_H
  3 
  4 #include <arduino.h>
  5 #include "CmdResp.h"
  6 #include "ArgInfo.h"
  7 
  8 // Abstract base class for all commands
  9 class Command : public CmdResp
 10 {
 11 public:
 12     // Gets the CommandCode for the command
 13     CommandCodes Code();
 14 
 15     // Gets the length of the buffer
 16     int Length();
 17 
 18     // Gets the buffer
 19     const byte* Buffer();
 20 
 21 protected:
 22     Command(const byte* buffer, int length);
 23 
 24     const byte* m_buffer;
 25     int m_length;
 26     //static ArgInfo argInfo;
 27 };
 28 
 29 // The rest of these are derived command classes
 30 
 31 class CmdNOP : public Command
 32 {
 33 public:
 34     CmdNOP(const byte* buffer, int length);
 35 
 36 protected:
 37     static const CommandCodes MY_CODE = NOP;
 38 };
 39 
 40 class CmdStatus : public Command
 41 {
 42 public:
 43     CmdStatus(const byte* buffer, int length);
 44 
 45 protected:
 46     static const CommandCodes MY_CODE = Status;
 47 };
 48 
 49 class CmdConfigure : public Command
 50 {
 51 public:
 52     CmdConfigure(const byte* buffer, int length);
 53 
 54     uint16_t GetConfig();
 55 
 56 protected:
 57     static const CommandCodes MY_CODE = Configure;
 58 };
 59 
 60 class CmdForceReset : public Command
 61 {
 62 public:
 63     CmdForceReset(const byte* buffer, int length);
 64 
 65 protected:
 66     static const CommandCodes MY_CODE = ForceReset;
 67 };
 68 
 69 class CmdEnablePins : public Command
 70 {
 71 public:
 72     CmdEnablePins(const byte* buffer, int length);
 73 
 74     bool GetEnable();
 75 
 76 protected:
 77     static const CommandCodes MY_CODE = EnablePins;
 78 };
 79 
 80 
 81 class CmdReadByte : public Command
 82 {
 83 public:
 84     CmdReadByte(const byte* buffer, int length);
 85 
 86     uint32_t GetAddress();
 87 
 88 protected:
 89     static const CommandCodes MY_CODE = ReadByte;
 90 };
 91 
 92 class CmdWriteByte : public Command
 93 {
 94 public:
 95     CmdWriteByte(const byte* buffer, int length);
 96 
 97     uint32_t GetAddress();
 98     uint8_t GetData();
 99 
100 protected:
101     static const CommandCodes MY_CODE = WriteByte;
102 };
103 
104 class CmdProgramByte : public Command
105 {
106 public:
107     CmdProgramByte(const byte* buffer, int length);
108 
109     uint32_t GetAddress();
110     uint8_t GetData();
111 
112 protected:
113     static const CommandCodes MY_CODE = ProgramByte;
114 };
115 
116 
117 class CmdReadBlock : public Command
118 {
119 public:
120     CmdReadBlock(const byte* buffer, int length);
121 
122     uint32_t GetAddress();
123     uint32_t GetLength();
124 
125 protected:
126     static const CommandCodes MY_CODE = ReadBlock;
127 };
128 
129 class CmdProgramBlock : public Command
130 {
131 public:
132     CmdProgramBlock(const byte* buffer, int length);
133 
134     uint32_t GetAddress();
135     uint32_t GetLength();
136 
137 protected:
138     static const CommandCodes MY_CODE = ProgramBlock;
139 };
140 
141 
142 class CmdEraseSector : public Command
143 {
144 public:
145     CmdEraseSector(const byte* buffer, int length);
146 
147     uint8_t GetSector();
148     uint8_t GetCount();
149 
150 protected:
151     static const CommandCodes MY_CODE = EraseSector;
152 };
153 
154 class CmdEraseChip : public Command
155 {
156 public:
157     CmdEraseChip(const byte* buffer, int length);
158 
159 protected:
160     static const CommandCodes MY_CODE = EraseChip;
161 };
162 
163 class CmdVerifyErase : public Command
164 {
165 public:
166     CmdVerifyErase(const byte* buffer, int length);
167 
168     uint32_t GetAddress();
169     uint32_t GetLength();
170 
171 protected:
172     static const CommandCodes MY_CODE = VerifyErase;
173 };
174 
175 class CmdBlockCRC : public Command
176 {
177 public:
178     CmdBlockCRC(const byte* buffer, int length);
179 
180     uint32_t GetAddress();
181     uint32_t GetLength();
182 
183 protected:
184     static const CommandCodes MY_CODE = BlockCRC;
185 };
186 
187 
188 class CmdDirectPinRead : public Command
189 {
190 public:
191     CmdDirectPinRead(const byte* buffer, int length);
192 
193     uint16_t GetMask();
194 
195 protected:
196     static const CommandCodes MY_CODE = DirectPinRead;
197 };
198 
199 class CmdDirectPinWrite : public Command
200 {
201 public:
202     CmdDirectPinWrite(const byte* buffer, int length);
203 
204     uint16_t GetMask();
205     uint16_t GetLevels();
206 
207 protected:
208     static const CommandCodes MY_CODE = DirectPinWrite;
209 };
210 
211 class CmdDirectPinMode : public Command
212 {
213 public:
214     CmdDirectPinMode(const byte* buffer, int length);
215 
216     uint8_t GetPin();
217     uint8_t GetMode();
218 
219 protected:
220     static const CommandCodes MY_CODE = DirectPinMode;
221 };
222 
223 
224 class CmdReadMem : public Command
225 {
226 public:
227     CmdReadMem(const byte* buffer, int length);
228 
229     uint16_t GetAddress();
230 
231 protected:
232     static const CommandCodes MY_CODE = ReadMem;
233 };
234 
235 class CmdFetchMem : public Command
236 {
237 public:
238     CmdFetchMem(const byte* buffer, int length);
239 
240     uint16_t GetAddress();
241 
242 protected:
243     static const CommandCodes MY_CODE = FetchMem;
244 };
245 
246 class CmdWriteMem : public Command
247 {
248 public:
249     CmdWriteMem(const byte* buffer, int length);
250 
251     uint16_t GetAddress();
252     uint8_t GetData();
253 
254 protected:
255     static const CommandCodes MY_CODE = WriteMem;
256 };
257 
258 class CmdReadPort : public Command
259 {
260 public:
261     CmdReadPort(const byte* buffer, int length);
262 
263     uint8_t GetPort();
264 
265 protected:
266     static const CommandCodes MY_CODE = ReadPort;
267 
268 };
269 
270 class CmdWritePort : public Command
271 {
272 public:
273     CmdWritePort(const byte* buffer, int length);
274 
275     uint8_t GetPort();
276     uint8_t GetData();
277 
278 protected:
279     static const CommandCodes MY_CODE = WritePort;
280 };
281 
282 #endif
283 
284 </arduino>

Commands.cpp

  1 #include "Commands.h"
  2 
  3 Command::Command(const byte* buffer, int length) : m_buffer(buffer), m_length(length)
  4 {
  5 }
  6 
  7 CommandCodes Command::Code()
  8 {
  9     return (CommandCodes)m_buffer[0];
 10 }
 11 
 12 int Command::Length()
 13 {
 14     return m_length;
 15 }
 16 
 17 const byte* Command::Buffer()
 18 {
 19     return m_buffer;
 20 }
 21 
 22 ArgInfo CmdResp::argInfo;
 23 
 24 CmdNOP::CmdNOP(const byte* buffer, int length) : Command(buffer, length) { }
 25 
 26 CmdStatus::CmdStatus(const byte* buffer, int length) : Command(buffer, length) { }
 27 
 28 CmdConfigure::CmdConfigure(const byte* buffer, int length) : Command(buffer, length) { }
 29 
 30 uint16_t CmdConfigure::GetConfig()
 31 {
 32     uint16_t data;
 33     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
 34     return data;
 35 }
 36 
 37 CmdForceReset::CmdForceReset(const byte* buffer, int length) : Command(buffer, length) { }
 38 
 39 CmdEnablePins::CmdEnablePins(const byte* buffer, int length) : Command(buffer, length) { }
 40 
 41 bool CmdEnablePins::GetEnable()
 42 {
 43     bool data;
 44     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
 45     return data;
 46 }
 47 
 48 CmdReadByte::CmdReadByte(const byte* buffer, int length) : Command(buffer, length) { }
 49 
 50 uint32_t CmdReadByte::GetAddress()
 51 {
 52     uint32_t data;
 53     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
 54     return data;
 55 }
 56 
 57 CmdWriteByte::CmdWriteByte(const byte* buffer, int length) : Command(buffer, length) { }
 58 
 59 uint32_t CmdWriteByte::GetAddress()
 60 {
 61     uint32_t data;
 62     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
 63     return data;
 64 }
 65 
 66 uint8_t CmdWriteByte::GetData()
 67 {
 68     uint8_t data;
 69     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
 70     return data;
 71 }
 72 
 73 
 74 CmdProgramByte::CmdProgramByte(const byte* buffer, int length) : Command(buffer, length) { }
 75 
 76 uint32_t CmdProgramByte::GetAddress()
 77 {
 78     uint32_t data;
 79     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
 80     return data;
 81 }
 82 
 83 uint8_t CmdProgramByte::GetData()
 84 {
 85     uint8_t data;
 86     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
 87     return data;
 88 }
 89 
 90 
 91 CmdReadBlock::CmdReadBlock(const byte* buffer, int length) : Command(buffer, length) { }
 92 
 93 uint32_t CmdReadBlock::GetAddress()
 94 {
 95     uint32_t data;
 96     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
 97     return data;
 98 }
 99 
100 uint32_t CmdReadBlock::GetLength()
101 {
102     uint32_t data;
103     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
104     return data;
105 }
106 
107 
108 CmdProgramBlock::CmdProgramBlock(const byte* buffer, int length) : Command(buffer, length) { }
109 
110 uint32_t CmdProgramBlock::GetAddress()
111 {
112     uint32_t data;
113     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
114     return data;
115 }
116 
117 uint32_t CmdProgramBlock::GetLength()
118 {
119     uint32_t data;
120     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
121     return data;
122 }
123 
124 CmdEraseSector::CmdEraseSector(const byte* buffer, int length) : Command(buffer, length) { }
125 
126 uint8_t CmdEraseSector::GetSector()
127 {
128     uint8_t data;
129     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
130     return data;
131 }
132 
133 uint8_t CmdEraseSector::GetCount()
134 {
135     uint8_t data;
136     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
137     return data;
138 }
139 
140 CmdEraseChip::CmdEraseChip(const byte* buffer, int length) : Command(buffer, length) { }
141 
142 CmdVerifyErase::CmdVerifyErase(const byte* buffer, int length) : Command(buffer, length) { }
143 
144 uint32_t CmdVerifyErase::GetAddress()
145 {
146     uint32_t data;
147     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
148     return data;
149 }
150 
151 uint32_t CmdVerifyErase::GetLength()
152 {
153     uint32_t data;
154     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
155     return data;
156 }
157 
158 CmdBlockCRC::CmdBlockCRC(const byte* buffer, int length) : Command(buffer, length) { }
159 
160 uint32_t CmdBlockCRC::GetAddress()
161 {
162     uint32_t data;
163     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
164     return data;
165 }
166 
167 uint32_t CmdBlockCRC::GetLength()
168 {
169     uint32_t data;
170     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
171     return data;
172 }
173 
174 CmdDirectPinRead::CmdDirectPinRead(const byte* buffer, int length) : Command(buffer, length) { }
175 
176 uint16_t CmdDirectPinRead::GetMask()
177 {
178     uint16_t data;
179     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
180     return data;
181 }
182 
183 CmdDirectPinWrite::CmdDirectPinWrite(const byte* buffer, int length) : Command(buffer, length) { }
184 
185 uint16_t CmdDirectPinWrite::GetMask()
186 {
187     uint16_t data;
188     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
189     return data;
190 }
191 
192 uint16_t CmdDirectPinWrite::GetLevels()
193 {
194     uint16_t data;
195     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
196     return data;
197 }
198 
199 CmdDirectPinMode::CmdDirectPinMode(const byte* buffer, int length) : Command(buffer, length) { }
200 
201 uint8_t CmdDirectPinMode::GetPin()
202 {
203     uint8_t data;
204     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
205     return data;
206 }
207 uint8_t CmdDirectPinMode::GetMode()
208 {
209     uint8_t data;
210     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
211     return data;
212 }
213 
214 CmdReadMem::CmdReadMem(const byte* buffer, int length) : Command(buffer, length) { }
215 
216 uint16_t CmdReadMem::GetAddress()
217 {
218     uint16_t data;
219     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
220     return data;
221 }
222 
223 CmdFetchMem::CmdFetchMem(const byte* buffer, int length) : Command(buffer, length) { }
224 
225 uint16_t CmdFetchMem::GetAddress()
226 {
227     uint16_t data;
228     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
229     return data;
230 }
231 
232 CmdWriteMem::CmdWriteMem(const byte* buffer, int length) : Command(buffer, length) { }
233 
234 uint16_t CmdWriteMem::GetAddress()
235 {
236     uint16_t data;
237     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
238     return data;
239 }
240 uint8_t CmdWriteMem::GetData()
241 {
242     uint8_t data;
243     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
244     return data;
245 }
246 
247 CmdReadPort::CmdReadPort(const byte* buffer, int length) : Command(buffer, length) { }
248 
249 uint8_t CmdReadPort::GetPort()
250 {
251     uint8_t data;
252     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
253     return data;
254 }
255 
256 CmdWritePort::CmdWritePort(const byte* buffer, int length) : Command(buffer, length) { }
257 
258 uint8_t CmdWritePort::GetPort()
259 {
260     uint8_t data;
261     argInfo.CommandExtract(MY_CODE, 0, m_buffer, &data);
262     return data;
263 }
264 uint8_t CmdWritePort::GetData()
265 {
266     uint8_t data;
267     argInfo.CommandExtract(MY_CODE, 1, m_buffer, &data);
268     return data;
269 }

Responses.h

  1 #ifndef INCLUDED_RESPONSES_H
  2 #define INCLUDED_RESPONSES_H
  3 
  4 #include <arduino.h>
  5 #include "Commands.h"
  6 #include "CommandCodeEnum.h"
  7 #include "CmdResp.h"
  8 
  9 // Abstract base class for all responses
 10 class Response : public CmdResp
 11 {
 12 protected:
 13     Response(Command& command, uint8_t* buffer256);
 14 
 15 public:
 16     void SetResult(int result);
 17     int Length();
 18     CommandCodes Code();
 19 
 20 protected:
 21     Command& m_command;
 22     uint8_t* m_buffer256;
 23     //static ArgInfo argInfo;
 24 };
 25 
 26 // The rest of these are derived response classes
 27 
 28 class RespNOP : public Response
 29 {
 30 public:
 31     RespNOP(CmdNOP& cmd, uint8_t* buffer256); 
 32 };
 33 
 34 class RespStatus : public Response 
 35 {
 36 public:
 37     RespStatus(CmdStatus& cmd, uint8_t* buffer256);
 38 
 39     bool SetStatus(uint32_t data);
 40 };
 41 
 42 class RespConfigure : public Response 
 43 { 
 44 public:
 45     RespConfigure(CmdConfigure& cmd, uint8_t* buffer256);
 46 };
 47 
 48 class RespForceReset : public Response 
 49 {
 50 public:
 51     RespForceReset(CmdForceReset& cmd, uint8_t* buffer256);
 52 };
 53 
 54 class RespEnablePins : public Response 
 55 { 
 56 public:
 57     RespEnablePins(CmdEnablePins& cmd, uint8_t* buffer256);
 58 };
 59 
 60 class RespReadByte : public Response 
 61 { 
 62 public:
 63     RespReadByte(CmdReadByte& cmd, uint8_t* buffer256);
 64 
 65     bool SetData(uint8_t data);
 66 };
 67 class RespWriteByte : public Response 
 68 { 
 69 public:
 70     RespWriteByte(CmdWriteByte& cmd, uint8_t* buffer256);
 71 };
 72 
 73 class RespProgramByte : public Response 
 74 { 
 75 public:
 76     RespProgramByte(CmdProgramByte& cmd, uint8_t* buffer256);
 77 };
 78 
 79 class RespReadBlock : public Response 
 80 { 
 81 public:
 82     RespReadBlock(CmdReadBlock& cmd, uint8_t* buffer256);
 83 };
 84 
 85 class RespProgramBlock : public Response 
 86 { 
 87 public:
 88     RespProgramBlock(CmdProgramBlock& cmd, uint8_t* buffer256);
 89 };
 90 
 91 class RespEraseSector : public Response 
 92 { 
 93 public:
 94     RespEraseSector(CmdEraseSector& cmd, uint8_t* buffer256);
 95 };
 96 class RespEraseChip : public Response 
 97 { 
 98 public:
 99     RespEraseChip(CmdEraseChip& cmd, uint8_t* buffer256);
100 };
101 
102 class RespVerifyErase : public Response 
103 { 
104 public:
105     RespVerifyErase(CmdVerifyErase& cmd, uint8_t* buffer256);
106 
107     bool SetErrorCount(uint32_t data);
108 };
109 
110 class RespBlockCRC : public Response 
111 { 
112 public:
113     RespBlockCRC(CmdBlockCRC& cmd, uint8_t* buffer256);
114 
115     bool SetCRC(uint32_t crc);
116 };
117 
118 class RespDirectPinRead : public Response 
119 { 
120 public:
121     RespDirectPinRead(CmdDirectPinRead& cmd, uint8_t* buffer256);
122     bool SetPins(uint16_t pins);
123 };
124 
125 class RespDirectPinWrite : public Response 
126 { 
127 public:
128     RespDirectPinWrite(CmdDirectPinWrite& cmd, uint8_t* buffer256);
129 };
130 
131 class RespDirectPinMode : public Response 
132 { 
133 public:
134     RespDirectPinMode(CmdDirectPinMode& cmd, uint8_t* buffer256);
135 };
136 
137 class RespReadMem : public Response 
138 { 
139 public:
140     RespReadMem(CmdReadMem& cmd, uint8_t* buffer256);
141 
142     bool SetData(uint8_t data);
143 };
144 
145 class RespFetchMem : public Response 
146 { 
147 public:
148     RespFetchMem(CmdFetchMem& cmd, uint8_t* buffer256);
149 
150     bool SetData(uint8_t data);
151 };
152 
153 class RespWriteMem : public Response 
154 { 
155 public:
156     RespWriteMem(CmdWriteMem& cmd, uint8_t* buffer256);
157 };
158 
159 class RespReadPort : public Response 
160 { 
161 public:
162     RespReadPort(CmdReadPort& cmd, uint8_t* buffer256);
163 
164     bool SetData(uint8_t data);
165 };
166 
167 class RespWritePort : public Response 
168 { 
169 public:
170     RespWritePort(CmdWritePort& cmd, uint8_t* buffer256);
171 };
172 
173 
174 #endif
175 </arduino>

Responses.cpp

 1 #include "Responses.h"
 2 
 3 Response::Response(Command& command, uint8_t* buffer256) : m_command(command), m_buffer256(buffer256)
 4 {
 5     memcpy(m_buffer256, m_command.Buffer(), m_command.Length());
 6 }
 7 
 8 void Response::SetResult(int result)
 9 {
10     int length = Length();
11     m_buffer256[length - 1] = result;
12 }
13 
14 int Response::Length()
15 {
16     return argInfo.ResponseLength(m_command.Code());
17 }
18 
19 CommandCodes Response::Code()
20 {
21     return m_command.Code();
22 }
23 
24 RespNOP::RespNOP(CmdNOP& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
25 RespStatus::RespStatus(CmdStatus& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
26 RespConfigure::RespConfigure(CmdConfigure& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
27 RespForceReset::RespForceReset(CmdForceReset& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
28 RespEnablePins::RespEnablePins(CmdEnablePins& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
29 RespReadByte::RespReadByte(CmdReadByte& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
30 RespWriteByte::RespWriteByte(CmdWriteByte& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
31 RespProgramByte::RespProgramByte(CmdProgramByte& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
32 RespReadBlock::RespReadBlock(CmdReadBlock& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
33 RespProgramBlock::RespProgramBlock(CmdProgramBlock& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
34 RespEraseSector::RespEraseSector(CmdEraseSector& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
35 RespEraseChip::RespEraseChip(CmdEraseChip& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
36 RespVerifyErase::RespVerifyErase(CmdVerifyErase& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
37 RespBlockCRC::RespBlockCRC(CmdBlockCRC& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
38 RespDirectPinRead::RespDirectPinRead(CmdDirectPinRead& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
39 RespDirectPinWrite::RespDirectPinWrite(CmdDirectPinWrite& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
40 RespDirectPinMode::RespDirectPinMode(CmdDirectPinMode& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
41 RespReadMem::RespReadMem(CmdReadMem& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
42 RespFetchMem::RespFetchMem(CmdFetchMem& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
43 RespWriteMem::RespWriteMem(CmdWriteMem& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
44 RespReadPort::RespReadPort(CmdReadPort& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
45 RespWritePort::RespWritePort(CmdWritePort& cmd, uint8_t* buffer256) : Response(cmd, buffer256) {}
46 
47 bool RespStatus::SetStatus(uint32_t data)
48 {
49     return argInfo.ResponseInsert(Code(), 0, m_buffer256, data);
50 }
51 
52 bool RespReadByte::SetData(uint8_t data)
53 {
54     return argInfo.ResponseInsert(Code(), 0, m_buffer256, data);
55 }
56 
57 bool RespReadMem::SetData(uint8_t data)
58 {
59     return argInfo.ResponseInsert(Code(), 0, m_buffer256, data);
60 }
61 
62 bool RespFetchMem::SetData(uint8_t data)
63 {
64     return argInfo.ResponseInsert(Code(), 0, m_buffer256, data);
65 }
66 
67 bool RespReadPort::SetData(uint8_t data)
68 {
69     return argInfo.ResponseInsert(Code(), 0, m_buffer256, data);
70 }
71 
72 bool RespVerifyErase::SetErrorCount(uint32_t data)
73 {
74     return argInfo.ResponseInsert(Code(), 0, m_buffer256, data);
75 }
76 
77 bool RespBlockCRC::SetCRC(uint32_t crc)
78 {
79     return argInfo.ResponseInsert(Code(), 0, m_buffer256, crc);
80 }
81 
82 bool RespDirectPinRead::SetPins(uint16_t pins)
83 {
84     return argInfo.ResponseInsert(Code(), 0, m_buffer256, pins);
85 }

CmdResp.h

 1 #ifndef INCLUDED_CMDRESP_H
 2 #define INCLUDED_CMDRESP_H
 3 
 4 #include <arduino.h>
 5 #include "ArgInfo.h"
 6 class CmdResp
 7 {
 8  protected:
 9     static ArgInfo argInfo;
10 };
11 
12 #endif
13 
14 </arduino>

CommandCodeEnum.h

 1 #ifndef INCLUDED_COMMANDCODEENUM_H
 2 #define INCLUDED_COMMANDCODEENUM_H
 3 
 4 enum CommandCodes
 5 {
 6     NOP = 0x00,
 7     Status = 0x01,
 8     Configure = 0x02,
 9     ForceReset = 0x08,
10     EnablePins = 0x09,
11 
12     ReadByte = 0x10,
13     WriteByte = 0x11,
14     ProgramByte = 0x12,
15 
16     ReadBlock = 0x20,
17     ProgramBlock = 0x22,
18 
19     EraseSector = 0x30,
20     EraseChip = 0x33,
21 
22     VerifyErase = 0x40,
23     BlockCRC = 0x41,
24 
25     DirectPinRead = 0x80,
26     DirectPinWrite = 0x81,
27     DirectPinMode = 0x82,
28 
29     ReadMem = 0x90,
30     FetchMem = 0x91,
31     WriteMem = 0x92,
32     ReadPort = 0x98,
33     WritePort = 0x99
34 };
35 
36 #endif