📄 example280x_i2c_slave.c
字号:
//###########################################################################
//
// FILE: i2c_slave.c
//
// TITLE: DSP280x I2C SLAVE EXAMPLE
//
// ASSUMPTIONS:
//
// This program requires the DSP280x header files.
// This project is configured for "boot to SARAM" operation.
//
// This program will allow the I2C to act as a slave. External
// connections must be made to the I2C Clock and Data pins.
//
// Signal 2808 Pin eZdsp Pin
// I2C Clock GPIO33 (pin 5) P8-38
// I2C Data GPIO32 (pin 100) P8-36
// Ground Vss (pin 2) P8-40
//
// DESCRIPTION:
//
// This program will create 6 read/write locations in the 2808 RAM. It will
// allow communications with those registers by the following I2C commands:
//
// I2C Write (from host)
//
// S ADDR W A DATA A DATA A DATA A P
//
// S = Start bit
// ADDR = Device Address (7 bits - to this 2808)
// W = Write
// A = Acknowledge (from 2808 to host)
// DATA = location number (0 - 5)
// A = Acknowledge (from 2808)
// DATA = High byte of word to be stored
// A = Ack
// DATA = Low byte of word to be stored
// A = Ack
// P = Stop bit
//
//
// I2C Read (from host)
//
// S ADDR W A DATA A S ADDR R A DATA A DATA A P
//
// S = Start bit
// ADDR = Device Address (7 bits - to this 2808)
// W = Write
// A = Acknowledge (from 2808 to host)
// DATA = location number (0 - 5)
// A = Acknowledge (from 2808)
//
// S = Repeated Start Bit
// ADDR = Device Address (7 bits - to this 2808)
// R = Read
// A = Acknowlege (from 2808)
// DATA = High byte of word to be read
// A = Ack (from host)
// DATA = Low byte of word to be read
// A = (N)Ack (from host)
// P = Stop bit
//
//###########################################################################
// Author: Todd Anderson
//
// September, 2006
//###########################################################################
// Change Log
//---------------------------------------------------------------------------
// Date Change
//---------------------------------------------------------------------------
// 9/08/2006 Initial slave code received from Houston.
// Sent slave address with value AA to verify initial
// operation.
// Added 6 registers that can be updated: Reg[0] - Reg[5].
// Flag register added. (Use DataReady bit on I2C.)
// Added InData and OutData arrays to process I2C data.
// Added Main "while" loop to update regs with received data.
//---------------------------------------------------------------------------
#include "DSP280x_Device.h" // DSP280x Headerfile Include File
#include "DSP280x_Examples.h" // DSP280x Examples Include File
#include "DSP280x_I2C_defines.h"
// Note: I2C Macros used in this example can be found in the
// DSP280x_I2C_defines.h file
// Prototype statements for functions found within this file.
void I2CA_Init(void);
interrupt void i2c_int1a_isr(void);
struct FLAGREG_BITS
{
volatile unsigned int Rsvd:15; //bits 0-14
volatile unsigned int DataReady:1; // Bit 15
};
union FLAG_REG
{
volatile unsigned int all;
struct FLAGREG_BITS bit;
}Flags;
Uint16 Register;
Uint16 Reg[6] = {0,0,0,0,0,0};
Uint16 InData[3];
Uint16 OutData[3];
Uint16 I2cIndex;
void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP280x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// Setup only the GP I/O only for I2C functionality
InitI2CGpio();
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP280x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP280x_DefaultIsr.c.
// This function is found in DSP280x_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.I2CINT1A = &i2c_int1a_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
I2cIndex = 0;
Flags.bit.DataReady = 0;
// Step 4. Initialize all the Device Peripherals:
I2CA_Init();
// Enable interrupts required for this example
// Enable I2C interrupt 1 in the PIE: Group 8 interrupt 1
PieCtrlRegs.PIEIER8.bit.INTx1 = 1;
// Enable CPU INT8 which is connected to PIE group 8
IER |= M_INT8;
EINT;
// Application loop
while(1)
{
if (Flags.bit.DataReady == 1)
{
switch (Register)
{
case 0:
Reg[0] = (InData[1]<<8) | InData[2]; // Update register value.
break;
case 1:
Reg[1] = (InData[1]<<8) | InData[2]; // Update register value.
break;
case 2:
Reg[2] = (InData[1]<<8) | InData[2]; // Update register value.
break;
case 3:
Reg[3] = (InData[1]<<8) | InData[2]; // Update register value.
break;
case 4:
Reg[4] = (InData[1]<<8) | InData[2]; // Update register value.
break;
case 5:
Reg[5] = (InData[1]<<8) | InData[2]; // Update register value.
break;
default:
break;
}
Flags.bit.DataReady = 0;
}
}
} // end of main
void I2CA_Init(void)
{
// Initialize I2C
I2caRegs.I2COAR = 0x002C; // Own address
I2caRegs.I2CPSC.all = 9; // Prescaler - need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero
I2caRegs.I2CCNT = 1; // Get 1 byte
I2caRegs.I2CIER.all = 0x18; // Clear interrupts (was 0)
I2caRegs.I2CSTR.bit.RRDY = 1; // Clear flag
I2caRegs.I2CIER.bit.RRDY = 1; // Enable Receive Interrupt
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
// Stop I2C when suspended
return;
}
interrupt void i2c_int1a_isr(void) // I2C-A
{
Uint16 IntSource;
// Read interrupt source
IntSource = I2caRegs.I2CISRC.bit.INTCODE & 0x7;
switch(IntSource)
{
case I2C_NO_ISRC: // =0
break;
case I2C_ARB_ISRC: // =1
break;
case I2C_NACK_ISRC: // =2
break;
case I2C_ARDY_ISRC: // =3
break;
case I2C_RX_ISRC: // =4
InData[I2cIndex++] = I2caRegs.I2CDRR;
Register = InData[0]; // Used on data transmit.
OutData[1] = (Reg[Register]>>8)&0xFF; //Get most significant byte.
OutData[2] = (Reg[Register])&0xFF; //Get least significant byte.
if (I2cIndex == 3) // If index is at 3, we have received 2 data bytes.
{
I2cIndex = 0; // Reset index.
Flags.bit.DataReady = 1; // Set flag to update outside of this loop.
}
break;
case I2C_TX_ISRC: // =5
if (I2cIndex == 0) break; // If reset already, break.
I2caRegs.I2CDXR = OutData[I2cIndex++]; // Output Data to Host
if (I2cIndex ==3) // if index is at 3, we are done.
{
I2cIndex =0; // reset index.
}
break;
case I2C_SCD_ISRC: // =6
break;
case I2C_AAS_ISRC: // =7
break;
default:
asm(" ESTOP0"); // Halt on invalid number.
}
// Enable further I2C (PIE Group 8) interrupts by acknowledging this one.
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}
//===========================================================================
// No more.
//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -