MemCheckState.h
Go to the documentation of this file.
1 /****
2  * MemCheckState.h
3  *
4  * Copyright 2021 mikee47 <mike@sillyhouse.net>
5  *
6  * This file is part of the HardwareSPI Library
7  *
8  * This library is free software: you can redistribute it and/or modify it under the terms of the
9  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with this library.
16  * If not, see <https://www.gnu.org/licenses/>.
17  *
18  ****/
19 
20 #pragma once
21 
22 #include <S1D13781/Driver.h>
23 #include <S1D13781/registers.h>
24 
25 namespace HSPI
26 {
27 namespace Test
28 {
62 class MemCheckState
63 {
64 public:
65  MemCheckState(MemoryDevice& device) : device(device), maxAddr(device.getSize())
66  {
67  }
68 
69  virtual ~MemCheckState()
70  {
71  }
72 
73  void execute()
74  {
75  device.controller.stats.clear();
76  buildBlock();
77  writeBlock();
78  readBlock();
79  buildBlock();
80  }
81 
83 
84 protected:
94  virtual void fillBlock(uint32_t addr, uint32_t* buffer, size_t size)
95  {
96  os_get_random(reinterpret_cast<uint8_t*>(buffer), size * 4);
97  }
98 
99 private:
100  void buildBlock()
101  {
102  fillBlock(writeAddr, writeBuffer[bufIndex], bufSize / 4);
103  }
104 
105  void writeBlock()
106  {
107  device.write(reqWr, writeAddr, writeBuffer[bufIndex], bufSize);
108  writeAddr += bufSize;
109  bufIndex = 1 - bufIndex;
110  }
111 
112  void readBlock()
113  {
114  auto callback = [](Request& request) -> bool {
115  System.queueCallback([](void* param) { static_cast<MemCheckState*>(param)->blockRead(); }, request.param);
116  return true;
117  };
118  device.read(reqRd, readAddr, readBuffer, bufSize, callback, this);
119  }
120 
121  void blockRead()
122  {
123  if(writeAddr < maxAddr) {
124  writeBlock();
125  } else {
126  bufIndex = 1 - bufIndex;
127  }
128 
129  checkBlock();
130  readAddr += bufSize;
131  if(readAddr < maxAddr) {
132  readBlock();
133  if(writeAddr < maxAddr) {
134  buildBlock();
135  }
136  } else {
137  complete();
138  }
139  }
140 
141  void checkBlock()
142  {
143  if(memcmp(readBuffer, writeBuffer[bufIndex], bufSize)) {
144  debug_e("Mem check failed between 0x%08x and 0x%08x", readAddr, readAddr + bufSize - 1);
145 
146  unsigned checklen = ARRAY_SIZE(readBuffer);
147  for(unsigned i = 0; i < checklen; ++i) {
148  auto in = readBuffer[i];
149  auto out = writeBuffer[bufIndex][i];
150  if(in != out) {
151  debug_e(" @ 0x%08x: out 0x%08x in 0x%08x", readAddr + (i * 4), out, in);
152  break;
153  }
154  }
155  }
156  }
157 
158  void complete()
159  {
160  auto& stats = device.controller.stats;
161  debug_i("Memory check complete, %s, waitCycles = %u, trans = %u", timer.elapsedTime().toString().c_str(),
162  stats.waitCycles, stats.transCount);
163 
164  debug_i("out = %u, in = %u", reqWr.busy, reqRd.busy);
165 
166  auto callback = onComplete;
167 
168  delete this;
169 
170  if(callback) {
171  callback();
172  }
173  }
174 
175 private:
176  MemoryDevice& device;
177  uint32_t maxAddr;
178  static const unsigned bufSize{512};
179  uint32_t writeBuffer[2][bufSize / 4];
180  uint32_t readBuffer[bufSize / 4];
181  ElapseTimer timer;
182  uint32_t writeAddr{0};
183  uint32_t readAddr{0};
184  uint8_t bufIndex{0};
185  Request reqRd, reqWr;
186 };
187 
188 } // namespace Test
189 } // namespace HSPI
Definition: Common.h:34
virtual ~MemCheckState()
Definition: MemCheckState.h:120
volatile uint8_t busy
Request in progress.
Definition: HardwareSPI/src/include/HSPI/Request.h:86
Template class to implement a polled timer.
Definition: PolledTimer.h:67
#define ARRAY_SIZE(a)
Definition: stringutil.h:76
void execute()
Definition: MemCheckState.h:124
virtual void fillBlock(uint32_t addr, uint32_t *buffer, size_t size)
Fill buffer with test data.
Definition: MemCheckState.h:145
SystemClass System
Global instance of system object.
#define debug_e(fmt,...)
Definition: debug_progmem.h:77
static bool queueCallback(TaskCallback32 callback, uint32_t param=0)
Queue a deferred callback.
MemCheckState(MemoryDevice &device)
Definition: MemCheckState.h:116
NanoTime::Time< TimeType > elapsedTime() const
Get elapsed time since start() was last called.
Definition: PolledTimer.h:186
void read(uint32_t address, void *buffer, size_t len)
Read a block of data.
Definition: MemoryDevice.h:212
Controller & controller
Definition: Libraries/HardwareSPI/src/include/HSPI/Device.h:255
void write(uint32_t address, const void *data, size_t len)
Write a block of data.
Definition: MemoryDevice.h:107
InterruptDelegate onComplete
Definition: MemCheckState.h:133
#define debug_i
Definition: debug_progmem.h:107