[XMC1300 EVM] - SPI 테스트 (Infineon Cortex-M0)
XMC 시리즈는 시리얼 통신( UART, SPI, I2S, I2C )을 동일한 블록으로 만들어 두고 모드로 선택해서 사용할수 있도록 되어 있다.
장단점이 있을것 같은데...
장점으로 동일한 셋팅으로 사하기 때문에 소프트웨어 부담이 줄어든다. 반면 2채널 밖에 없기 때문에 여러 통신을 동시에 사용할때 어려움이 있다.
XMC1300 SPI 블록도
XMC1300 SPI 핀맵
XMC의 핀기능은 하나의 포트에 여러가지 기능을 사가능하도록 해 두었는데, 다만 기능들이 일관성이 없어 데이터시트 상에 핀의 기능을 확인할 때 주의가 필요한것 같다.
SPI 기능핀은 여러핀 리맵가능한것 처럼 되어 있지만 사실 상당히 제한적으로 설정 가능하다. 데이터시트를 자세히 보고 할당해야 한다. XMC1300 EVM 보드에서는 아래와 같이 할당 했다.
P1.0(MOSI) - USIC0_CH0.DOUT0(ALT7)
P1.1(MISO) - USIC0_CH0.DX0D
P0.8(SCLK) - USIC0_CH0.SCLKOUT(ALT6)
P1.4(SS) - USIC0_CH0.SELO0(ALT6)
SPI MISO 기능으로 사용할 수 있는 핀
XMC1300 SPI 관련 레지스터
CCR (Channel Control Register)
MODE [3:0] rw Operating Mode
0H - USIC channel is disabled
1H - SSC (SPI) 모드로 동작
2H - ASC (SCI, UART) 모드로 동작
3H - I2S 모드로 동작
4H - I2C 모드로 동작
XMC1300 SPI 초기화 함수
void SPI0_Init(void)
{
PORT1_Set_Mode(1,INPUT_PU);
PORT1_Set_Mode(0,OUTPUT_PP_AF7);
PORT0_Set_Mode(8,OUTPUT_PP_AF6);
//Kernel State Configuration Register - Module Enable + Bit Protection for MODEN
USIC0_CH0->KSCFG |= (1 << USIC_CH_KSCFG_MODEN_Pos) | (1 << USIC_CH_KSCFG_BPMODEN_Pos);
//Normal divider mode selected
WR_REG(USIC0_CH0->FDR, USIC_CH_FDR_DM_Msk, USIC_CH_FDR_DM_Pos, 1);
//Configuration of baud rate
WR_REG(USIC0_CH0->FDR, USIC_CH_FDR_STEP_Msk, USIC_CH_FDR_STEP_Pos, FDR_STEP);
WR_REG(USIC0_CH0->BRG, USIC_CH_BRG_PDIV_Msk, USIC_CH_BRG_PDIV_Pos, BRG_PDIV);
WR_REG(USIC0_CH0->BRG, USIC_CH_BRG_SCLKOSEL_Msk, USIC_CH_BRG_SCLKOSEL_Pos, 0);
WR_REG(USIC0_CH0->BRG, USIC_CH_BRG_SCLKCFG_Msk, USIC_CH_BRG_SCLKCFG_Pos, 1);
//Configuration of USIC Input Stage
//Select P1.2
WR_REG(USIC0_CH0->DX0CR, USIC_CH_DX0CR_DSEL_Msk, USIC_CH_DX0CR_DSEL_Pos, 3);
WR_REG(USIC0_CH0->DX0CR, USIC_CH_DX0CR_INSW_Msk, USIC_CH_DX0CR_INSW_Pos, 1);
//Configuration of USIC Shift Control
//Transmit/Receive MSB first is selected, Transmission Mode (TRM) = 1, Passive Data Level (PDL) = 1
WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_PDL_Msk, USIC_CH_SCTR_PDL_Pos, 1);
WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_TRM_Msk, USIC_CH_SCTR_TRM_Pos, 1);
WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_SDIR_Msk, USIC_CH_SCTR_SDIR_Pos, 1);
//Set Word Length (WLE) & Frame Length (FLE)
WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_FLE_Msk, USIC_CH_SCTR_FLE_Pos, 7);
WR_REG(USIC0_CH0->SCTR, USIC_CH_SCTR_WLE_Msk, USIC_CH_SCTR_WLE_Pos, 7);
//Configuration of USIC Transmit Control/Status Register
//TBUF Data Enable (TDEN) = 1, TBUF Data Single Shot Mode (TDSSM) = 1
WR_REG(USIC0_CH0->TCSR, USIC_CH_TCSR_TDEN_Msk, USIC_CH_TCSR_TDEN_Pos, 1);
WR_REG(USIC0_CH0->TCSR, USIC_CH_TCSR_TDSSM_Msk, USIC_CH_TCSR_TDSSM_Pos, 1);
//Configuration of Protocol Control Register
WR_REG(USIC0_CH0->PCR_SSCMode, USIC_CH_PCR_SSCMode_MSLSEN_Msk, USIC_CH_PCR_SSCMode_MSLSEN_Pos, 1);
//Configuration of Channel Control Register
WR_REG(USIC0_CH0->CCR, USIC_CH_CCR_MODE_Msk, USIC_CH_CCR_MODE_Pos, 1);
WR_REG(USIC0_CH0->CCR, USIC_CH_CCR_AIEN_Msk, USIC_CH_CCR_AIEN_Pos, 0);
//Data Pointer & Buffer Size for Transmitter Buffer Control - DPTR = 0, SIZE = 5
WR_REG(USIC0_CH0->TBCTR, USIC_CH_TBCTR_DPTRSIZE_Msk, USIC_CH_TBCTR_DPTRSIZE_Pos, 0x05000000);
//Data Pointer & Buffer Size for Receiver Buffer Control - DPTR = 32, SIZE = 5
WR_REG(USIC0_CH0->RBCTR, USIC_CH_RBCTR_DPTRSIZE_Msk, USIC_CH_RBCTR_DPTRSIZE_Pos, 0x05000020);
}
XMC1300 SPI Read/Write 함수
unsigned char SPI0_WriteReadByte(unsigned char Data)
{
//while(!(USIC0_CH0->TRBSR&BIT11));
USIC0_CH0->IN[0] = Data;
while(USIC0_CH0->TRBSR&BIT3);
return USIC0_CH0->OUTR;
}