과정 요약하면,
TC27x 메모리맵이 담긴 헤더파일과 AUTOSAR Driver 형식이 적힌 PDF 파일을 가지고, TC275TP 보드 메모리 주소에 값을 넣을 수 있는 함수를 작성한다.
코드 작성 시 MISRA-C, AUTOSAR 형식을 지키며, 값 넣을 때 비트 자릿수는 비트필드구조체가 헤더에 있으니 F3 눌러 파악해서 하고, 이해 안되면 메뉴얼이랑 비교해가면서 파악하고, 핀넘버, 채널ID 같은 개인 변수는 임의로 지정해 사용한다.
빌드되면 라우터바흐 디버거 연결해서 T32에서 디버깅, LD 누르고 go 또는 Step으로 코드 동작 확인, LD 안되면 Run Script - T32 - demo - tricore - flash - tc27x.cmm (다른거 건들면 고장!)
/*****************************************************
*
* my_project.c
*
* Description : Hello World in C, ANSI-style
*
*/
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef uint32_t Port_PinType;
typedef uint32_t Port_PinModeType;
typedef uint8_t Dio_LevelType;
typedef uint32_t Dio_ChannelType;
#include "IfxPort_reg.h"
typedef enum
{
PORT_PIN_IN = 0x0U,
PORT_PIN_OUT = 0x1U
}Port_PinDirectionType;
#define PORT_PIN_MODE_GPIO (0x0U)
#define PORT_PIN_MODE_ALT1 (0x1U)
#define PORT_PIN_MODE_ALT2 (0x2U)
#define PORT_PIN_MODE_ALT3 (0x3U)
#define PORT_PIN_MODE_ALT4 (0x4U)
#define PORT_PIN_MODE_ALT5 (0x5U)
#define PORT_PIN_MODE_ALT6 (0x6U)
#define PORT_PIN_MODE_ALT7 (0x7U)
#define P11_6 (0x100U) // LED pin
//#define P11_7 (0x101U)
#define STD_LOW (0x00U)
#define STD_HIGH (0x01U)
void Dio_WriteChannel(Dio_ChannelType ChannelId, Dio_LevelType Level)
{
switch(ChannelId)
{
case P11_6 :
MODULE_P11.OUT.B.P6 = Level;
break;
// case P11_7 :
// MODULE_P11.OUT.B.P7 = Level;
// break;
default :
break;
}
}
Dio_LevelType Dio_ReadChannel(Dio_ChannelType ChannelId)
{
switch(ChannelId)
{
case P11_6 :
return MODULE_P11.OUT.B.P6;
// case P11_7 :
// return MODULE_P11.OUT.B.P6;
default :
return 0; // 예외처리 필요
}
}
void Port_SetPinDirection(Port_PinType Pin, Port_PinDirectionType Direction)
{
MODULE_P11.IOCR4.B.PC6 &= ~(0x1)<<4;
MODULE_P11.IOCR4.B.PC6 |= Direction << 4; // 0xF003B114 주소 19번 자리부터 4번째, 23번자리 In/Out 결정
}
void Port_SetPinMode(Port_PinType Pin, Port_PinModeType Mode)
{
switch(Pin)
{
case P11_6 :
MODULE_P11.IOCR4.B.PC6 &= ~(0xF);
MODULE_P11.IOCR4.B.PC6 |= Mode; // 0xF003B114 주소 19번 자리부터 Mode 결정
break;
// case P11_7 :
// MODULE_P11.IOCR4.B.PC6 &= ~(0xF);
// MODULE_P11.IOCR4.B.PC6 |= Mode;
// break;
default :
break;
}
}
int32_t main(void)
{
volatile uint8_t led_state;
Port_SetPinDirection(P11_6, PORT_PIN_OUT);
Port_SetPinMode(P11_6, PORT_PIN_MODE_GPIO);
Dio_WriteChannel(P11_6, STD_HIGH);
led_state = Dio_ReadChannel(P11_6);
Dio_WriteChannel(P11_6, STD_LOW);
led_state = Dio_ReadChannel(P11_6);
Dio_WriteChannel(P11_6, STD_HIGH);
led_state = Dio_ReadChannel(P11_6);
Dio_WriteChannel(P11_6, STD_LOW);
led_state = Dio_ReadChannel(P11_6);
for(;;)
{
Dio_WriteChannel(P11_6, STD_HIGH);
for(uint32_t i=0; i<0xffffff; i++);
Dio_WriteChannel(P11_6, STD_LOW);
for(uint32_t i=0; i<0xffffff; i++);
}
}
유저메뉴얼에서 P11 base address 보면 0xF003B100, 플젝파일에 헤더파일
넣으면 TC27x 메모리 맵 사용 가능
MODULE_P11.IOCR4.B.PC6 |= Direction << 4;
// 0xF003B114 주소 19번 자리부터 4번째, 23번자리 In/Out 결정
// 앞에 비트필드구조체인데 0xF003B114 주소를 가리키는 포인터변수
뜯어보면,
#define MODULE_P11 (*(Ifx_P*)0xF003B100u)
typedef volatile struct _Ifx_P
{
Ifx_P_OUT OUT; /**< \brief 0, Port Output Register */
Ifx_P_OMR OMR; /**< \brief 4, Port Output Modification Register */
Ifx_P_ID ID; /**< \brief 8, Identification Register */
unsigned char reserved_C[4]; /**< \brief C, \internal Reserved */
Ifx_P_IOCR0 IOCR0; /**< \brief 10, Port Input/Output Control Register 0 */
Ifx_P_IOCR4 IOCR4; /**< \brief 14, Port Input/Output Control Register 4 */
Ifx_P_IOCR8 IOCR8; /**< \brief 18, Port Input/Output Control Register 8 */
Ifx_P_IOCR12 IOCR12; /**< \brief 1C,Port Input/Output Control Register 12 */
...
} Ifx_P;
typedef union
{
unsigned int U; /**< \brief Unsigned access */
signed int I; /**< \brief Signed access */
Ifx_P_IOCR4_Bits B; /**< \brief Bitfield access */
} Ifx_P_IOCR4;
typedef struct _Ifx_P_IOCR4_Bits
{
unsigned int reserved_0:3; /**< \brief \internal Reserved */
unsigned int PC4:5; /**< \brief [7:3] (rw) */
unsigned int reserved_8:3; /**< \brief \internal Reserved */
unsigned int PC5:5; /**< \brief [15:11] (rw) */
unsigned int reserved_16:3; /**< \brief \internal Reserved */
unsigned int PC6:5; /**< \brief [23:19] (rw) */
unsigned int reserved_24:3; /**< \brief \internal Reserved */
unsigned int PC7:5; /**< \brief [31:27] (rw) */
} Ifx_P_IOCR4_Bits;
struct MY_STRUCT // 32바이트 아니고 32비트짜리 구조체
{
unsigned int A:3;
unsigned int B:5;
unsigned int C:3;
unsigned int D:5;
unsigned int E:3;
unsigned int F:5;
unsigned int G:3;
unsigned int H:5;
};
int32_t main(void)
{
volatile struct MY_STRUCT var;
for(;;)
{
var.A = 0x7; // MY_STRUCT 주소 가서 [2:0] 111
var.B = 0x10; // MY_STRUCT 주소 가서 [7:3] 10000
}
}