summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/pcf8583.h
blob: 2086eeef6bf6ca7347b7be592e6f208c1a960550 (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
170
171
172
173
174
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/*********************************************************************

    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"


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// ======================> pcf8583_device

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);

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

	void set_a0(int a0) { m_slave_address = (m_slave_address & 0xfd) | (a0 << 1); }

	void a0_w(int state);
	void scl_w(int state);
	void sda_w(int state);
	int sda_r();

protected:
	// device-level overrides
	virtual void device_start() override;

	// device_rtc_interface overrides
	virtual bool rtc_feature_y2k() const override { return true; }
	virtual bool rtc_feature_leap_year() 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 bool nvram_read(util::read_stream &file) override;
	virtual bool nvram_write(util::write_stream &file) override;

	TIMER_CALLBACK_MEMBER(clock_tick);

private:
	static constexpr uint8_t PCF8583_SLAVE_ADDRESS = 0xa0;

	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 = 7
	};

	// 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 advance_hundredths();

	optional_memory_region m_region;

	devcb_write_line m_irq_cb;

	// internal state
	uint8_t m_data[256];
	int m_slave_address;
	int m_scl;
	int m_sdaw;
	int m_sdar;
	int m_state;
	int m_bits;
	int m_shift;
	int m_devsel;
	int m_register;
	bool m_irq;
	emu_timer * m_timer;

	enum { STATE_IDLE, STATE_DEVSEL, STATE_REGISTER, STATE_DATAIN, STATE_DATAOUT, STATE_READSELACK };
};

// device type definition
DECLARE_DEVICE_TYPE(PCF8583, pcf8583_device)

#endif // MAME_MACHINE_PCF8583_H