summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/pcf8583.h
blob: f8d98295cb16d4f0f5b86eb7f34cf50ef6de2a09 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// license:BSD-3-Clause
// copyright-holders:Tim Schuerewegen, Ryan Holtz
/*********************************************************************

    Philips PCF8583 Clock and Calendar with 240 x 8-bit RAM

**********************************************************************

    The PCF8583 comes in three package configurations:

        PCF8583P  - 8-pin dual-inline package (DIP8)
        PCF8583T  - 8-pin small-outline package (SO8)
        PCF8583BS - 20-pin thin quad-flat package (HVQFN20)

**********************************************************************

    DIP8 pinning:           ____  ____
                           |    \/    |
                  OSCI   1 |          | 8   Vdd
                  OSCI   2 |          | 7   /INT
                    A0   3 | PCF8583P | 6   SCL
                   Vss   4 |          | 5   SDA
                           |__________|

**********************************************************************

    SO8 pinning:            _____  _____
                           | |   \/     |
                  OSCI   1 | |          | 8   Vdd
                  OSCI   2 | |          | 7   /INT
                    A0   3 | | PCF8583P | 6   SCL
                   Vss   4 | |          | 5   SDA
                           |_|__________|

**********************************************************************

    HVQFN20 pinning:
                          NC NC NC NC NC
                          20 19 18 17 16
                        __________________
                       |                  |
                       |    __________    |
                       |   |          |   |
                NC   1 |   |          |   | 15  Vdd
              OSCI   2 |   |          |   | 14  /INT
              OSCO   3 |   | PCF8583BS|   | 13  SCL
                A0   4 |   |          |   | 12  SDA
               Vss   5 |   |          |   | 11  NC
                       |   |__________|   |
                       |                  |
                       |__________________|
                           6  7  8  9 10
                          NC NC NC NC NC

*********************************************************************/

#ifndef MAME_MACHINE_PCF8583_H
#define MAME_MACHINE_PCF8583_H

#pragma once

#include "dirtc.h"


class pcf8583_device :  public device_t,
						public device_rtc_interface,
						public device_nvram_interface
{
public:
	pcf8583_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 32'768);

	auto irq() { return m_irq_callback.bind(); }

	void set_a0(uint8_t a0);

	DECLARE_WRITE_LINE_MEMBER(scl_w);
	DECLARE_WRITE_LINE_MEMBER(sda_w);
	DECLARE_READ_LINE_MEMBER(sda_r);

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

	// device_rtc_interface overrides
	virtual bool rtc_feature_y2k() const override { return true; }
	virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override;

	// device_nvram_interface overrides
	virtual void nvram_default() override;
	virtual void nvram_read(emu_file &file) override;
	virtual void nvram_write(emu_file &file) override;

private:
	enum
	{
		REG_CONTROL             = 0x00,
		REG_HUNDREDTHS          = 0x01,
		REG_SECONDS             = 0x02,
		REG_MINUTES             = 0x03,
		REG_HOURS               = 0x04,
		REG_YEAR_DATE           = 0x05,
		REG_MONTH_DAY           = 0x06,
		REG_TIMER               = 0x07,
		REG_ALARM_CONTROL       = 0x08,
		REG_ALARM_HUNDREDTHS    = 0x09,
		REG_ALARM_SECONDS       = 0x0a,
		REG_ALARM_MINUTES       = 0x0b,
		REG_ALARM_HOURS         = 0x0c,
		REG_ALARM_DATE          = 0x0d,
		REG_ALARM_MONTH         = 0x0e,
		REG_ALARM_TIMER         = 0x0f
	};

	enum
	{
		CONTROL_STOP_BIT    = 0x80
	};

	static const device_timer_id TIMER_TICK = 0;

	// get/set date
	uint8_t get_date_year()             { return (m_data[REG_YEAR_DATE] >> 6) & 3; }
	void set_date_year(uint8_t year)    { m_data[REG_YEAR_DATE] = (m_data[REG_YEAR_DATE] & 0x3f) | ((year % 4) << 6); }
	uint8_t get_date_month()            { return bcd_to_integer(m_data[6] & 0x1f); }
	void set_date_month(uint8_t month)  { m_data[REG_MONTH_DAY] = (m_data[REG_MONTH_DAY] & 0xe0) | (convert_to_bcd(month) & 0x1f); }
	uint8_t get_date_day()              { return bcd_to_integer(m_data[REG_YEAR_DATE] & 0x3f); }
	void set_date_day(uint8_t day)      { m_data[REG_YEAR_DATE] = (m_data[REG_YEAR_DATE] & 0xc0) | (convert_to_bcd(day) & 0x3f); }

	// get/set time
	uint8_t get_time_hour()             { return bcd_to_integer(m_data[REG_HOURS]); }
	void set_time_hour(uint8_t hour)    { m_data[REG_HOURS] = convert_to_bcd(hour); }
	uint8_t get_time_minute()           { return bcd_to_integer(m_data[REG_MINUTES]); }
	void set_time_minute(uint8_t minute){ m_data[REG_MINUTES] = convert_to_bcd(minute); }
	uint8_t get_time_second()           { return bcd_to_integer(m_data[REG_SECONDS]); }
	void set_time_second(uint8_t second){ m_data[REG_SECONDS] = convert_to_bcd(second); }

	void write_register(uint8_t offset, uint8_t data);
	void advance_hundredths();
	void clear_rx_buffer();

	devcb_write_line m_irq_callback;

	// internal state
	uint8_t     m_data[256];
	int         m_scl;
	int         m_sda;
	int         m_inp;
	bool        m_transfer_active;
	int         m_bit_index;
	bool        m_irq;
	uint8_t     m_data_recv_index;
	uint8_t     m_data_recv;
	uint8_t     m_mode;
	uint8_t     m_pos;
	uint8_t     m_write_address;
	uint8_t     m_read_address;
	emu_timer * m_timer;
	enum        { RTC_MODE_NONE, RTC_MODE_SEND, RTC_MODE_RECV };

	static constexpr uint8_t WRITE_ADDRESS_BASE = 0xa0;
	static constexpr uint8_t READ_ADDRESS_BASE = 0xa1;
};

// device type definition
DECLARE_DEVICE_TYPE(PCF8583, pcf8583_device)

#endif // MAME_MACHINE_PCF8583_H