sim_peripheral.h Source File

yasimavr: sim_peripheral.h Source File
yasimavr
Loading...
Searching...
No Matches
sim_peripheral.h
Go to the documentation of this file.
1/*
2 * sim_peripheral.h
3 *
4 * Copyright 2022-2026 Clement Savergne <csavergne@yahoo.com>
5
6 This file is part of yasim-avr.
7
8 yasim-avr is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 yasim-avr is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with yasim-avr. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22//=======================================================================================
23
24#ifndef __YASIMAVR_PERIPHERAL_H__
25#define __YASIMAVR_PERIPHERAL_H__
26
27#include "sim_ioreg.h"
28#include "sim_signal.h"
29#include "sim_logger.h"
30
32
33class Device;
35class CycleTimer;
36enum class SleepMode;
37
38
39//=======================================================================================
57constexpr sim_id_t AVR_IOCTL_CORE = "CORE";
59constexpr sim_id_t AVR_IOCTL_WDT = "WDT";
61constexpr sim_id_t AVR_IOCTL_INTR = "CPUINT";
63constexpr sim_id_t AVR_IOCTL_SLEEP = "SLPCTRL";
65constexpr sim_id_t AVR_IOCTL_CLOCK = "CLKCTRL";
67constexpr sim_id_t AVR_IOCTL_PORT(char c) { return sim_id_t("PORT") + c; }
69constexpr sim_id_t AVR_IOCTL_PORTMUX = "PORTMUX";
71constexpr sim_id_t AVR_IOCTL_ADC(char c) { return sim_id_t("ADC") + c; }
73constexpr sim_id_t AVR_IOCTL_ACP(char c) { return sim_id_t("ACP") + c; }
75constexpr sim_id_t AVR_IOCTL_TIMER(char t, char c) { return (sim_id_t("TC") + t) + c; }
77constexpr sim_id_t AVR_IOCTL_EEPROM = "EEPROM";
79constexpr sim_id_t AVR_IOCTL_NVM = "NVMCTRL";
81constexpr sim_id_t AVR_IOCTL_VREF = "VREF";
83constexpr sim_id_t AVR_IOCTL_EXTINT = "EXTINT";
85constexpr sim_id_t AVR_IOCTL_RST = "RSTCTRL";
87constexpr sim_id_t AVR_IOCTL_RTC = "RTC";
89constexpr sim_id_t AVR_IOCTL_UART(char c) { return sim_id_t("USART") + c; }
91constexpr sim_id_t AVR_IOCTL_SPI(char c) { return sim_id_t("SPI") + c; }
93constexpr sim_id_t AVR_IOCTL_TWI(char c) { return sim_id_t("TWI") + c; }
94
96
97//=======================================================================================
98
111typedef int ctlreq_id_t;
112
113
118#define AVR_CTLREQ_BASE 0x100
119
125#define AVR_CTLREQ_GET_SIGNAL 0
126
130#define AVR_CTLREQ_CORE_BREAK (AVR_CTLREQ_BASE + 1)
131
136#define AVR_CTLREQ_CORE_SLEEP (AVR_CTLREQ_BASE + 2)
137
141#define AVR_CTLREQ_CORE_WAKEUP (AVR_CTLREQ_BASE + 3)
142
146#define AVR_CTLREQ_CORE_SHORTING (AVR_CTLREQ_BASE + 4)
147
153#define AVR_CTLREQ_CORE_CRASH (AVR_CTLREQ_BASE + 5)
154
159#define AVR_CTLREQ_CORE_RESET (AVR_CTLREQ_BASE + 6)
160
165#define AVR_CTLREQ_CORE_RESET_FLAG (AVR_CTLREQ_BASE + 7)
166
171#define AVR_CTLREQ_CORE_NVM (AVR_CTLREQ_BASE + 8)
172
177#define AVR_CTLREQ_CORE_HALT (AVR_CTLREQ_BASE + 9)
178
183#define AVR_CTLREQ_CORE_SECTIONS (AVR_CTLREQ_BASE + 10)
184
188#define AVR_CTLREQ_WATCHDOG_RESET (AVR_CTLREQ_BASE + 1)
189
195#define AVR_CTLREQ_NVM_REQUEST (AVR_CTLREQ_BASE + 1)
196
200#define AVR_CTLREQ_SLEEP_CALL (AVR_CTLREQ_BASE + 1)
201
205#define AVR_CTLREQ_SLEEP_PSEUDO (AVR_CTLREQ_BASE + 2)
206
208
209
222 unsigned char kind;
224 int nvm;
228 uint16_t data;
230 signed char result;
232 unsigned short cycles;
233};
234
235
239 long long index;
240};
241
242
243//=======================================================================================
253 uint64_t reg_value;
254};
255
256template<typename T>
257int find_reg_config(const std::vector<T>& v, uint64_t reg_value)
258{
259 for (auto it = v.cbegin(); it != v.cend(); ++it) {
260 const base_reg_config_t* cfg = &(*it);
261 if (cfg->reg_value == reg_value)
262 return it - v.cbegin();
263 }
264 return -1;
265}
266
267template<typename T>
268const T* find_reg_config_p(const std::vector<T>& v, uint64_t reg_value)
269{
270 for (const T& cfg : v) {
271 if (cfg.reg_value == reg_value)
272 return &cfg;
273 }
274 return nullptr;
275}
276
279
280
281//=======================================================================================
287
288public:
289
290 explicit Peripheral(ctl_id_t id);
291 virtual ~Peripheral();
292
293 ctl_id_t id() const;
294 std::string name() const;
295
296 virtual bool init(Device& device);
297
298 virtual void reset(int flags);
299
300 virtual bool ctlreq(ctlreq_id_t req, ctlreq_data_t* data);
301
302 virtual uint8_t ioreg_read_handler(reg_addr_t addr, uint8_t value) override;
303
304 virtual uint8_t ioreg_peek_handler(reg_addr_t addr, uint8_t value) override;
305
306 virtual void ioreg_write_handler(reg_addr_t addr, const ioreg_write_t& data) override;
307
308 virtual void sleep(bool on, SleepMode mode);
309
310 Peripheral(const Peripheral&) = delete;
311 Peripheral& operator=(const Peripheral&) = delete;
312
313protected:
314
315 Device* device() const;
316
317 Logger& logger();
318
324 void add_ioreg(const regmask_t& rm, IORegister::BitMode bitmode = IORegister::RW);
325 void add_ioreg(const regbit_compound_t& rbc, IORegister::BitMode bitmode = IORegister::RW);
326 void add_ioreg(reg_addr_t addr, IORegister::BitMode bitmode = IORegister::RW);
327 void add_ioreg(reg_addr_t addr, bitmask_t mask, IORegister::BitMode bitmode = IORegister::RW);
329
335 uint8_t read_ioreg(const regbit_t& rb) const;
336 uint64_t read_ioreg(const regbit_compound_t& rbc) const;
337 uint8_t read_ioreg(reg_addr_t addr) const;
338 uint8_t read_ioreg(reg_addr_t addr, const bitspec_t& bs) const;
339
340 bool test_ioreg(const regbit_t& rb) const;
341 bool test_ioreg(const regbit_compound_t& rbc) const;
342 bool test_ioreg(reg_addr_t addr, const bitspec_t& bs) const;
343 bool test_ioreg(reg_addr_t addr, bitmask_t bm = 0xFF) const;
344
345 void write_ioreg(reg_addr_t addr, bitmask_t bm, uint8_t value);
346 void write_ioreg(const regbit_t& rb, uint8_t value);
347 void write_ioreg(const regbit_compound_t& rbc, uint64_t value);
348 void write_ioreg(reg_addr_t addr, uint8_t value);
349 void write_ioreg(reg_addr_t addr, const bitspec_t& bs, uint8_t value);
350
351 void set_ioreg(reg_addr_t addr, bitmask_t bm = 0xFF);
352 void set_ioreg(const regbit_t& rb);
353 void set_ioreg(const regbit_compound_t& rbc);
354 void set_ioreg(reg_addr_t addr, const bitspec_t& bs);
355
356 void clear_ioreg(reg_addr_t addr, bitmask_t bm = 0xFF);
357 void clear_ioreg(const regbit_t& rb);
358 void clear_ioreg(const regbit_compound_t& rbc);
359 void clear_ioreg(reg_addr_t addr, const bitspec_t& bs);
361
362 bool register_interrupt(int_vect_t vector, InterruptHandler& handler) const;
363
364 Signal* get_signal(ctl_id_t ctl_id) const;
365
366private:
367
368 ctl_id_t m_id;
369 Device* m_device;
370 Logger m_logger;
371
372};
373
376{
377 return m_id;
378}
379
382{
383 return m_device;
384}
385
388{
389 return m_logger;
390}
391
393{
394 add_ioreg(rm.addr, rm.mask, bitmode);
395}
396
398{
399 add_ioreg(addr, bitmask_t(0xFF), bitmode);
400}
401
402inline uint8_t Peripheral::read_ioreg(const regbit_t& rb) const
403{
404 return rb.extract(read_ioreg(rb.addr));
405}
406
407inline uint8_t Peripheral::read_ioreg(reg_addr_t addr, const bitspec_t& bs) const
408{
409 return bs.extract(read_ioreg(addr));
410}
411
412inline bool Peripheral::test_ioreg(const regbit_t& rb) const
413{
414 return !!read_ioreg(rb);
415}
416
417inline bool Peripheral::test_ioreg(const regbit_compound_t& rbc) const
418{
419 return !!read_ioreg(rbc);
420}
421
422inline bool Peripheral::test_ioreg(reg_addr_t addr, const bitspec_t& bs) const
423{
424 return !!read_ioreg(addr, bs);
425}
426
427inline bool Peripheral::test_ioreg(reg_addr_t addr, bitmask_t bm) const
428{
429 return !!(bm & read_ioreg(addr));
430}
431
432inline void Peripheral::write_ioreg(const regbit_t& rb, uint8_t value)
433{
434 write_ioreg(rb.addr, (bitmask_t) rb, rb.shift_and_mask(value));
435}
436
437inline void Peripheral::write_ioreg(reg_addr_t addr, uint8_t value)
438{
439 write_ioreg(addr, bitmask_t(0xFF), value);
440}
441
442inline void Peripheral::write_ioreg(reg_addr_t addr, const bitspec_t& bs, uint8_t value)
443{
444 write_ioreg(addr, (bitmask_t) bs, bs.shift_and_mask(value));
445}
446
448{
449 write_ioreg(addr, bm, 0xFF);
450}
451
452inline void Peripheral::set_ioreg(const regbit_t& rb)
453{
454 write_ioreg(rb, 0xFF);
455}
456
457inline void Peripheral::set_ioreg(reg_addr_t addr, const bitspec_t& bs)
458{
459 write_ioreg(addr, bs, 0xFF);
460}
461
463{
464 write_ioreg(addr, bm, 0x00);
465}
466
467inline void Peripheral::clear_ioreg(const regbit_t& rb)
468{
469 write_ioreg(rb, 0x00);
470}
471
472inline void Peripheral::clear_ioreg(reg_addr_t addr, const bitspec_t& bs)
473{
474 write_ioreg(addr, bs, 0x00);
475}
476
477
478//=======================================================================================
486
487public:
488
491 uint8_t reset;
492 };
493
494 DummyController(ctl_id_t id, const std::vector<dummy_register_t>& regs);
495
496 virtual bool init(Device& device) override;
497 virtual void reset(int flags) override;
498
499private:
500
501 const std::vector<dummy_register_t> m_registers;
502
503};
504
505
507
508#endif //__YASIMAVR_PERIPHERAL_H__
Definition sim_cycle_timer.h:41
Basic AVR device model.
Definition sim_device.h:61
Generic dummy peripheral.
Definition sim_peripheral.h:485
Definition sim_ioreg.h:69
virtual uint8_t ioreg_read_handler(reg_addr_t addr, uint8_t value)=0
virtual uint8_t ioreg_peek_handler(reg_addr_t addr, uint8_t value)=0
virtual void ioreg_write_handler(reg_addr_t addr, const ioreg_write_t &data)=0
BitMode
Definition sim_ioreg.h:120
@ RW
Read&Write mode.
Definition sim_ioreg.h:121
Abstract interface to a interrupt controller.
Definition sim_interrupt.h:221
Definition sim_logger.h:91
Abstract class defining a framework for MCU peripherals.
Definition sim_peripheral.h:286
Peripheral(const Peripheral &)=delete
uint8_t read_ioreg(const regbit_t &rb) const
Definition sim_peripheral.h:402
Device * device() const
Access to the device. It is null before init() is called.
Definition sim_peripheral.h:381
void clear_ioreg(reg_addr_t addr, bitmask_t bm=0xFF)
Definition sim_peripheral.h:462
void write_ioreg(reg_addr_t addr, bitmask_t bm, uint8_t value)
Definition sim_peripheral.cpp:160
bool test_ioreg(const regbit_t &rb) const
Definition sim_peripheral.h:412
Logger & logger()
Logging object associated with this peripheral.
Definition sim_peripheral.h:387
void add_ioreg(const regmask_t &rm, IORegister::BitMode bitmode=IORegister::RW)
Definition sim_peripheral.h:392
Peripheral & operator=(const Peripheral &)=delete
ctl_id_t id() const
Unique identifier of the peripheral.
Definition sim_peripheral.h:375
void set_ioreg(reg_addr_t addr, bitmask_t bm=0xFF)
Definition sim_peripheral.h:447
Signalling framework class.
Definition sim_signal.h:97
bit spec structure. Represent a field in a I/O register. It works the same as bitmask_t except used b...
Definition sim_types.h:287
constexpr uint8_t shift_and_mask(uint8_t value) const
Transform the field value to its true representation and position in the 8-bits of the register.
constexpr uint8_t extract(uint8_t reg) const
Extract the field value and shift right by the LSB.
Representation of a I/O register address, with validity state.
Definition sim_types.h:60
Definition sim_types.h:431
Represents a field in a I/O register with address.
Definition sim_types.h:348
reg_addr_t addr
Definition sim_types.h:355
constexpr uint8_t extract(uint8_t reg) const
Extract the field value and shift right by the LSB.
constexpr uint8_t shift_and_mask(uint8_t value) const
Transform the field value to its true representation and position in the 8-bits of the register.
Representation of a ID internally represented as a 64-bits integer but can be initialised with a stri...
Definition sim_types.h:627
Definition sim_types.h:495
constexpr sim_id_t AVR_IOCTL_RST
Definition sim_peripheral.h:85
constexpr sim_id_t AVR_IOCTL_CORE
Definition sim_peripheral.h:57
constexpr sim_id_t AVR_IOCTL_VREF
Definition sim_peripheral.h:81
const T * find_reg_config_p(const std::vector< T > &v, uint64_t reg_value)
Definition sim_peripheral.h:268
constexpr sim_id_t AVR_IOCTL_UART(char c)
Definition sim_peripheral.h:89
constexpr sim_id_t AVR_IOCTL_WDT
Definition sim_peripheral.h:59
constexpr sim_id_t AVR_IOCTL_SPI(char c)
Definition sim_peripheral.h:91
int ctlreq_id_t
Definition sim_peripheral.h:111
constexpr sim_id_t AVR_IOCTL_RTC
Definition sim_peripheral.h:87
constexpr sim_id_t AVR_IOCTL_SLEEP
Definition sim_peripheral.h:63
constexpr sim_id_t AVR_IOCTL_ACP(char c)
Definition sim_peripheral.h:73
constexpr sim_id_t AVR_IOCTL_ADC(char c)
Definition sim_peripheral.h:71
constexpr sim_id_t AVR_IOCTL_CLOCK
Definition sim_peripheral.h:65
constexpr sim_id_t AVR_IOCTL_NVM
Definition sim_peripheral.h:79
constexpr sim_id_t AVR_IOCTL_PORTMUX
Definition sim_peripheral.h:69
constexpr sim_id_t AVR_IOCTL_INTR
Definition sim_peripheral.h:61
constexpr sim_id_t AVR_IOCTL_EXTINT
Definition sim_peripheral.h:83
constexpr sim_id_t AVR_IOCTL_TIMER(char t, char c)
Definition sim_peripheral.h:75
constexpr sim_id_t AVR_IOCTL_PORT(char c)
Definition sim_peripheral.h:67
constexpr sim_id_t AVR_IOCTL_TWI(char c)
Definition sim_peripheral.h:93
constexpr sim_id_t AVR_IOCTL_EEPROM
Definition sim_peripheral.h:77
int find_reg_config(const std::vector< T > &v, uint64_t reg_value)
Definition sim_peripheral.h:257
#define YASIMAVR_BEGIN_NAMESPACE
Definition sim_globals.h:58
#define AVR_CORE_PUBLIC_API
Definition sim_globals.h:46
#define YASIMAVR_END_NAMESPACE
Definition sim_globals.h:59
SleepMode
Definition sim_sleep.h:49
unsigned long mem_addr_t
Definition sim_types.h:41
short int_vect_t
Definition sim_types.h:43
Definition sim_peripheral.h:489
uint8_t reset
Reset value of the I/O register.
Definition sim_peripheral.h:491
regmask_t reg
Address and mask of the I/O register.
Definition sim_peripheral.h:490
Structure used for AVR_CTLREQ_NVM_REQUEST requests.
Definition sim_peripheral.h:220
unsigned short cycles
Number of cycles to be consumed, only for write (SPM) requests and if result>=0.
Definition sim_peripheral.h:232
uint16_t data
Value [to write to/read from] the NVM.
Definition sim_peripheral.h:228
signed char result
Result of the request : >0:success, 0:ignored, <0:error/refused.
Definition sim_peripheral.h:230
mem_addr_t addr
Address to write/read (in the appropriate block address space)
Definition sim_peripheral.h:226
int nvm
Memory block being written/read : -1 if unknown/irrelevant, otherwise one of AVR_NVM enumeration valu...
Definition sim_peripheral.h:224
unsigned char kind
Kind of request : 0:write (SPM), 1:read (LPM)
Definition sim_peripheral.h:222
Definition sim_peripheral.h:252
uint64_t reg_value
Definition sim_peripheral.h:253
Bit mask structure for bitwise operations on 8-bits registers.
Definition sim_types.h:86
Definition sim_peripheral.h:237
long long index
Definition sim_peripheral.h:239
vardata_t data
Definition sim_peripheral.h:238
Definition sim_ioreg.h:39
Address + bit mask structure.
Definition sim_types.h:156
bitmask_t mask
Definition sim_types.h:159
reg_addr_t addr
Definition sim_types.h:158