TM4C123 - SPI 테스트 (3축 가속도 센서)
TM4C123 의 SPI 기능을 테스트 해 보았다.
최대 SPI클럭이 25 MHz까지 동작 가능하고 FIFO를 내장하고 있다. 특이사항으로 4채널의 SPI블럭을 사용할 수 있어서 SPI블록이 많이 필요한 어플리케이션에 좋을것 같다.
TM4C123 EVM 보드에서는 PA2, PA3, PA4, PA5 에 SPI를 할당해 두었다.
TM4C123 의 SPI블록도
TM4C123 의 SPI 핀맵
TM4C 는 최대 4채널의 SPI모듈을 제공한다.
핀맵을 아래와같이 설정 가능하다.
TM4C123 의 SPI 초기화 함수
TI의 기존 Cortex-M3 코어와 코드를 호환하도록 제작되어 있기 때문에 코드 변경없이 그대로 사용가능하다. 물론 초기화 코드는 약간의 수정이 필요하다.
// SPI 통신 초기화 함수
void SPI0_Init(void)
{
// The SSI0 peripheral must be enabled for use.
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
// Configure the pin muxing for SSI0 functions on port A2, A3, A4, and A5.
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
ROM_GPIOPinConfigure(GPIO_PA2_SSI0CLK);
//ROM_GPIOPinConfigure(GPIO_PA3_SSI0FSS);
ROM_GPIOPinConfigure(GPIO_PA4_SSI0RX);
ROM_GPIOPinConfigure(GPIO_PA5_SSI0TX);
ROM_GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_2);
ROM_SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), _ssi0_mode,
SSI_MODE_MASTER, _ssi0_baud, 8);
// Enable the SSI0 module.
ROM_SSIEnable(SSI0_BASE);
}
TM4C123 의 SPI 송수신 함수
UINT SPI0_WriteReadByte(UINT Data)
{
unsigned long rx_data;
ROM_SSIDataPut(SSI0_BASE, Data);
ROM_SSIDataGet(SSI0_BASE, &rx_data);
return rx_data;
}
Sellaless SPI 테스트 예제 를 참고 하면 되는데 속도를 필요로 한다면 아무래도 레지스터를 직접 제어 하는것이 좋을것 같다.
UINT SPI0_WriteReadByte(UINT Data)
{
// Wait until there is space.
while(!(HWREG(SSI0_BASE + SSI_O_SR) & SSI_SR_TNF))
{
}
// Write the data to the SSI.
HWREG(SSI0_BASE + SSI_O_DR) = Data;
while(!(HWREG(SSI0_BASE + SSI_O_SR) & SSI_SR_RNE))
{
}
// Read data from SSI.
return (HWREG(SSI0_BASE + SSI_O_DR));
}
TM4C123 EVM - 3축 가속도 센서 드라이버 코드
//-----------------------------------------------------------------------------
// myAccel3LV02 HAL
#define MY_ACCEL3LV02_SPI_MODE 1
#define MY_ACCEL3LV02_I2C_MODE 0
#define ACCEL_CS_BIT BIT4
#define ACCEL_CS_PORT PORTB
#define ACCEL_CS_INIT() ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);\
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, ACCEL_CS_BIT);
#define ACCEL_CS_ASSERT() PB4 = 0
#define ACCEL_CS_DEASSERT() PB4 = ACCEL_CS_BIT;
#define ACCEL_SPI_INIT() SPI0_Init()
#define ACCEL_Read SPI0_WriteReadByte
#define ACCEL_Write SPI0_WriteReadByte
//-----------------------------------------------------------------------------
TM4C123 EVM - 3축 가속도 센서 예제 코드
int main(void)
{
short data;
SystemInit();
Led1Init();
Led1On();
Led2Init();
Led2On();
DebugInit(BAUD_115200);
DebugPrint("TM4C Uart Test\r\n");
myAccel3lvInit();
myAccel3lvWrite(CTRL_REG1, 0xC7); //1000.0111 Power on, enable all axis, self test off
DebugPrint("WHO_AM_I: %x\r\n", myAccel3lvRead(WHO_AM_I));
while(1)
{
if(DebugIsByte())
{
switch(U0_GetByte())
{
case '0':
Led1Off();
DebugPrint("LED OFF\r\n");
break;
case '1':
Led1On();
DebugPrint("LED ON\r\n");
break;
case 't':
DebugPrint("WHO_AM_I: %x\r\n", myAccel3lvRead(WHO_AM_I));
break;
case 'r':
GetAccelValue(AXIS_X, &data);
DebugPrint("%d\r\n", data);
break;
}
}
}
}