Numworks Epsilon  1.4.1
Graphing Calculator Operating System
dfu_interface.h
Go to the documentation of this file.
1 #ifndef ION_DEVICE_USB_DFU_INTERFACE_H
2 #define ION_DEVICE_USB_DFU_INTERFACE_H
3 
4 #include "device.h"
5 #include "interface.h"
6 #include "endpoint0.h"
7 #include "setup_packet.h"
8 #include "stack/streamable.h"
9 #include <stddef.h>
10 #include <assert.h>
11 
12 namespace Ion {
13 namespace USB {
14 namespace Device {
15 
16 class DFUInterface : public Interface {
17 
18 public:
19  DFUInterface(Device * device, Endpoint0 * ep0, uint8_t bInterfaceAlternateSetting) :
20  Interface(ep0),
21  m_device(device),
22  m_status(Status::OK),
23  m_state(State::dfuIDLE),
24  m_addressPointer(0),
25  m_potentialNewAddressPointer(0),
26  m_erasePage(k_flashMemorySectorsCount+1),
27  m_largeBuffer{0},
28  m_largeBufferLength(0),
29  m_writeAddress(0),
30  m_bInterfaceAlternateSetting(bInterfaceAlternateSetting)
31  {
32  }
33  void wholeDataReceivedCallback(SetupPacket * request, uint8_t * transferBuffer, uint16_t * transferBufferLength) override;
34  void wholeDataSentCallback(SetupPacket * request, uint8_t * transferBuffer, uint16_t * transferBufferLength) override;
35 
36 protected:
37  void setActiveInterfaceAlternative(uint8_t interfaceAlternativeIndex) override {
38  assert(interfaceAlternativeIndex == m_bInterfaceAlternateSetting);
39  }
41  return m_bInterfaceAlternateSetting;
42  }
43  bool processSetupInRequest(SetupPacket * request, uint8_t * transferBuffer, uint16_t * transferBufferLength, uint16_t transferBufferMaxLength) override;
44 
45 private:
46  // DFU Request Codes
47  enum class DFURequest {
48  Detach = 0,
49  Download = 1,
50  Upload = 2,
51  GetStatus = 3,
52  ClearStatus = 4,
53  GetState = 5,
54  Abort = 6
55  };
56 
57  // DFU Download Commmand Codes
58  enum class DFUDownloadCommand {
59  GetCommand = 0x00,
60  SetAddressPointer = 0x21,
61  Erase = 0x41,
62  ReadUnprotect = 0x92
63  };
64 
65  enum class Status : uint8_t {
66  OK = 0x00,
67  errTARGET = 0x01,
68  errFILE = 0x02,
69  errWRITE = 0x03,
70  errERASE = 0x04,
71  errCHECK_ERASED = 0x05,
72  errPROG = 0x06,
73  errVERIFY = 0x07,
74  errADDRESS = 0x08,
75  errNOTDONE = 0x09,
76  errFIRMWARE = 0x0A,
77  errVENDOR = 0x0B,
78  errUSBR = 0x0C,
79  errPOR = 0x0D,
80  errUNKNOWN = 0x0E,
81  errSTALLEDPKT = 0x0F
82  };
83 
84  enum class State : uint8_t {
85  appIDLE = 0,
86  appDETACH = 1,
87  dfuIDLE = 2,
88  dfuDNLOADSYNC = 3,
89  dfuDNBUSY = 4,
90  dfuDNLOADIDLE = 5,
91  dfuMANIFESTSYNC = 6,
92  dfuMANIFEST = 7,
93  dfuMANIFESTWAITRESET = 8,
94  dfuUPLOADIDLE = 9,
95  dfuERROR = 10
96  };
97 
98  class StatusData : public Streamable {
99  public:
100  StatusData(Status status, State state, uint32_t pollTimeout = 1) :
101  /* We put a default pollTimeout value of 1ms: if the device is busy, the
102  * host has to wait 1ms before sending a getStatus Request. */
103  m_bStatus((uint8_t)status),
104  m_bwPollTimeout{uint8_t((pollTimeout>>16) & 0xFF), uint8_t((pollTimeout>>8) & 0xFF), uint8_t(pollTimeout & 0xFF)},
105  m_bState((uint8_t)state),
106  m_iString(0)
107  {
108  }
109  protected:
110  void push(Channel * c) const override;
111  private:
112  uint8_t m_bStatus; // Status resulting from the execution of the most recent request
113  uint8_t m_bwPollTimeout[3]; // m_bwPollTimeout is 24 bits
114  uint8_t m_bState; // State of the device immediately following transmission of this response
115  uint8_t m_iString;
116  };
117 
118  class StateData : public Streamable {
119  public:
120  StateData(State state) : m_bState((uint8_t)state) {}
121  protected:
122  void push(Channel * c) const override;
123  private:
124  uint8_t m_bState; // Current state of the device
125  };
126 
127  constexpr static uint8_t k_flashMemorySectorsCount = 12;
128 
129  /* The Flash and SRAM addresses are in flash.ld. However, dfu_interface is
130  * linked with dfu.ld, so we cannot access the values. */
131  constexpr static uint32_t k_flashStartAddress = 0x08000000;
132  constexpr static uint32_t k_flashEndAddress = 0x08100000;
133  constexpr static uint32_t k_sramStartAddress = 0x20000000;
134  constexpr static uint32_t k_sramEndAddress = 0x20040000;
135 
136  // Download and upload
137  bool processDownloadRequest(uint16_t wLength, uint16_t * transferBufferLength);
138  bool processUploadRequest(SetupPacket * request, uint8_t * transferBuffer, uint16_t * transferBufferLength, uint16_t transferBufferMaxLength);
139  // Address pointer
140  void setAddressPointerCommand(SetupPacket * request, uint8_t * transferBuffer, uint16_t transferBufferLength);
141  void changeAddressPointerIfNeeded();
142  // Access memory
143  void eraseCommand(uint8_t * transferBuffer, uint16_t transferBufferLength);
144  void eraseMemoryIfNeeded();
145  void writeOnMemory();
146  void unlockFlashMemory();
147  void lockFlashMemoryAndPurgeCaches();
148  // Status
149  bool getStatus(SetupPacket * request, uint8_t * transferBuffer, uint16_t * transferBufferLength, uint16_t transferBufferMaxLength);
150  bool clearStatus(SetupPacket * request, uint8_t * transferBuffer, uint16_t * transferBufferLength, uint16_t transferBufferMaxLength);
151  // State
152  bool getState(uint8_t * transferBuffer, uint16_t * transferBufferLength, uint16_t maxSize);
153  // Abort
154  bool dfuAbort(uint16_t * transferBufferLength);
155  // Leave DFU
156  void leaveDFUAndReset();
157 
158  Device * m_device;
159  Status m_status;
160  State m_state;
161  uint32_t m_addressPointer;
162  uint32_t m_potentialNewAddressPointer;
163  uint32_t m_erasePage;
164  uint8_t m_largeBuffer[Endpoint0::MaxTransferSize];
165  uint16_t m_largeBufferLength;
166  uint32_t m_writeAddress;
167  uint8_t m_bInterfaceAlternateSetting;
168 };
169 
170 }
171 }
172 }
173 
174 #endif
void wholeDataSentCallback(SetupPacket *request, uint8_t *transferBuffer, uint16_t *transferBufferLength) override
#define assert(e)
Definition: assert.h:9
unsigned short uint16_t
Definition: stdint.h:5
unsigned char uint8_t
Definition: stdint.h:4
void wholeDataReceivedCallback(SetupPacket *request, uint8_t *transferBuffer, uint16_t *transferBufferLength) override
c(generic_all_nodes)
DFUInterface(Device *device, Endpoint0 *ep0, uint8_t bInterfaceAlternateSetting)
Definition: dfu_interface.h:19
unsigned int uint32_t
Definition: stdint.h:6
Definition: app.cpp:5
static constexpr int MaxTransferSize
Definition: endpoint0.h:26
bool processSetupInRequest(SetupPacket *request, uint8_t *transferBuffer, uint16_t *transferBufferLength, uint16_t transferBufferMaxLength) override
void setActiveInterfaceAlternative(uint8_t interfaceAlternativeIndex) override
Definition: dfu_interface.h:37
uint8_t getActiveInterfaceAlternative() override
Definition: dfu_interface.h:40
Definition: backlight.h:6