TinyEmu.h


/*
* TinyEmu.h
*
* Created: 17.09.2012 18:05:51
* Author: Mati
*/

/*
* Saab CD-Changer emulator / Aux-In Interface
* Copyright (C) 2012-2013  Mati Ustav <triibutu@hotmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef TINYEMU_H_
#define TINYEMU_H_

/* byte type. Love bytes */
typedef unsigned char byte;

/* Differences by MCU */
#if (defined (__AVR_ATtiny25__) || defined (__AVR_ATtiny45__) || defined (__AVR_ATiny82__))
# define TIMER_MASK TIMSK //Timer interrupt mask register
# define TIMER_TOP 63  //Counter top for 4ms period
#elif (defined (__AVR_ATtiny13__) || defined (__AVR_ATtiny13A__))
# define TIMER_MASK TIMSK0
# define TIMER_TOP 75
#else
# error This target MCU is not supported!
#endif


/*
* Message 1: CD Changer to HU
* @6A2:3200001601020000

* Message 2: CD Changer information
* @3C8:E0003F35FFFFFFD0
* Message:
* CHANGED - MAGAZINE DISC TRACK MIN SEC SECURITY
* Bytes:
* CHANGED: CHANGED - ?? - - - - - //Example: 20
* MAGAZINE: - - CD6 CD5 CD4 CD3 CD2 CD1  //Slot occupied: 1, empty: 0
* DISC:  - STAT2 STAT1 STAT0 DISC3 DISC2 DISC1 DISC0
* DISC3:0 - which disk is being played, in BCD coding, goes up to 9
* STAT2:0 - status of the CD changer. 0h = inactive (not spinning), 3h = power-up / spin-up, but not ready yet,
* 4h = everything is OK - playing disc.
* TRACK - which track is being played, in BCD coding
* MIN - track play minutes, in BCD coding
* SEC - track play seconds, in BCD coding
* SECURITY: D0 -> OK
*/

/* SPI port pins */
#define SPI_PORT   PORTB
#define SPI_PIN    PINB
#define MOSI    PINB0
#define MISO    PINB1
#define SCK     PINB2
#define CS     PINB3
#define INT     PINB4

/* Macros for SPI pin manipulation */
#define SPI_ENABLE   SPI_PORT &= ~(1<<CS)
#define SPI_DISABLE   SPI_PORT |=  (1<<CS)
#define MOSI_LOW   SPI_PORT &= ~(1<<MOSI)
#define MOSI_HIGH   SPI_PORT |= (1<<MOSI)
#define SCK_LOW    SPI_PORT &= ~(1<<SCK)
#define SCK_HIGH   SPI_PORT |= (1<<SCK)
#define IS_MISO_HIGH  (SPI_PIN & (1<<MISO))

/* CAN Standard ID register bytes from hex SID value */
#define SIDH(x)    ((x) >> 3)
#define SIDL(x)    (((x) & 0x07) << 5)

/* CAN Standard ID value from register bytes */
#define SID(x,y)   ((uint16_t)x << 3 | (y >> 5))


/* MCP2515 CAN bit timing calculation for 21 uS bit time @ 16 MHz
Fclk: 16MHz, Tclk = 1/Fclk

SJW = 01    1 (+1 = 2 TQ)
BRP = 001011   11 (+1 = 12)
BTL = 1     1
SAM = 1     1 (3 x sample)
PRSEG = 001    1 (+1 = 2 TQ)
PHSEG1 = 110   6 (+1 = 7 TQ)
PHSEG2 = 011   3 (+1 = 4 TQ)
TQ = 2*Tclk*(BRP+1)  0,0000015 = 1,5 uS
NBT = 1 + 2 + 7 + 4 = 14 TQ = 21 uS
Sample point: 10/14 = @ 71,4%

Check:
PropSeg + PS1 >= PS2
PropSeg + PS1 >= TDELAY
PS2 > SJW

==
Bit:   7       6      5       4       3       2       1       0
CNF1: SJW1    SJW0   BRP5    BRP4    BRP3    BRP2    BRP1    BRP0
CNF2: BTLMODE SAM    PHSEG12 PHSEG11 PHSEG10 PRSEG2  PRSEG1  PRSEG0
CNF3: SOF     WAKFIL —       —       —       PHSEG22 PHSEG21 PHSEG20

CNF1: 01001011 => 0x4B
CNF2: 11110001 => 0xF1
CNF3: 00000011 => 0x03
*/

/* MCP2515 bit timing registers for 21 uS bit time @ 16 MHz */
#define MCP_CNF1 0x4B
#define MCP_CNF2 0xF1
#define MCP_CNF3 0x03

/* MCP2515 SPI command codes */
#define SPI_RESET  0xC0
#define SPI_READ  0x03
#define SPI_READ_RX  0x90
#define SPI_WRITE  0x02
#define SPI_WRITE_TX 0x40
#define SPI_RTS   0x80
#define SPI_READ_STATUS 0xA0
#define SPI_RX_STATUS 0xB0
#define SPI_BIT_MODIFY 0x05

/* MCP2515 Register addresses */
#define TXRTSCTRL 0x0D
#define CANSTAT  0x0E
#define CANCTRL  0x0F
#define CNF3  0x28
#define CNF2  0x29
#define CNF1  0x2A
#define CANINTE  0x2B
#define CANINTF  0x2C
#define EFLG  0x2D

#define TXB0CTRL 0x30
#define TXB1CTRL 0x40
#define TXB2CTRL 0x50

/* Bits from TXBnCTRL */
#define TXREQ  3


/* Bits from CANINTE */
#define MERRE  7
#define WAKIE  6
#define ERRIE  5
#define TX2IE  4
#define TX1IE  3
#define TX0IE  2
#define RX1IE  1
#define RX0IE  0

/* Bits from CANINTF */
#define MERRF  7
#define WAKIF  6
#define ERRIF  5
#define TX2IF  4
#define TX1IF  3
#define TX0IF  2
#define RX1IF  1
#define RX0IF  0


/* Bits from CANCTRL */
#define REQOP2  7
#define REQOP1  6
#define REQOP0  5
#define ABAT  4
#define OSM   3
#define CLKEN  2
#define CLKPRE1  1
#define CLKPRE0  0

/* Bits from CANSTAT */
#define OPMOD2  7
#define OPMOD1  6
#define OPMOD0  5
#define ICOD2  3
#define ICOD1  2
#define ICOD0  1

/* RX buffers for SPI_READ_RX command */
#define RXB0  (SPI_READ_RX)
#define RXB1  (SPI_READ_RX + 4)

/* TX buffers for SPI_WRITE_TX command */
#define TXB0  (SPI_WRITE_TX)
#define TXB1  (SPI_WRITE_TX + 2)
#define TXB2  (SPI_WRITE_TX + 4)

/* SPI_RTS commands for each buffer */
#define TXB0RTS  (SPI_RTS + 1)
#define TXB1RTS  (SPI_RTS + 2)
#define TXB2RTS  (SPI_RTS + 4)

/* Register start addresses for filters and masks: RXB0
* SIDH, SIDL, EID8, EID0
*/
#define RXF0SIDH 0x00
#define RXF1SIDH 0x04
#define RXM0SIDH 0x20

/* Register start addresses for filters and masks: RXB1 */
#define RXF2SIDH 0x08
#define RXF3SIDH 0x10
#define RXF4SIDH 0x14
#define RXF5SIDH 0x18
#define RXM1SIDH 0x24

/* Byte addresses in TXB1 for CDC disc and track bytes */
#define CDC_DISC 0x49
#define CDC_TRACK 0x4A

/* MCP2515 operation modes */
#define MCP_MODE_NORMAL   0
#define MCP_MODE_CONFIGURATION (1<<REQOP2)
#define MCP_MODE_LISTENONLY  ((1<<REQOP1)|(1<<REQOP0))

/* What interrupts are enabled */
#define MCP_CANINTE  ((1<<RX0IE)|(1<<RX1IE)) //Enable receive interrupts


#endif /* TINYEMU_H_ */

No comments:

Post a Comment