Pardon me folks
So I'm currently programming an arm for a robot, and how our IC communicates to the motherboard is through UART protocol, sending and receiving data in the form of a struct with the commands contained within. One of the problems I've encountered is that the struct receive function that we designed requires the tiva C to receive 18 bytes, when its FIFO can only hold 16.
In order to successfully read all of the data without loss, I'm attempting to utilize the RX interrupt at 2/8 setting, so (as I understand it) it'll fire the interrupt once it 4 bytes are stored into the FIFO at once (if anyone knows an easier way to extend the FIFO's range, do let me know).
Anyway, the interrupt doesnt fire after I load the full 18 bytes into the receive buffer, and I'm not sure where I'm going wrong. Am I setting it up wrong or something? This is my first time really working with interrupts on TI microcontrollers so I might have missed something.
This is the initHardware function, which I use to initialize all of the hardware components including uart's and interrupts and gpio's:
void initHardware()
{
//
// Set the clocking to run directly from the main oscillator at 16 mhz
// The following code:
// -sets the system clock divider to 1
// -sets the system clock to use an oscillator
// -uses the main oscillator
// -configures for use of 16 MHz crystal/oscillator input
//
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);
//uart1: dynamixel
//
// Enable the peripherals used by this example.
// The UART itself needs to be enabled, as well as the GPIO port
// containing the pins that will be used.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
//
// Configure the GPIO pin muxing for the UART function.
// This is only necessary if your part supports GPIO pin function muxing.
// Study the data sheet to see which functions are allocated per pin.
//
GPIOPinConfigure(GPIO_PC4_U1RX);
GPIOPinConfigure(GPIO_PC5_U1TX);
//
// Since GPIO C4 and C5 are used for the UART function, they must be
// configured for use as a peripheral function (instead of GPIO).
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);
//
// Configure the UART for 115,200, 8-N-1 operation.
// This function uses SysCtlClockGet() to get the system clock
// frequency. This could be also be a variable or hard coded value
// instead of a function call.
//
UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 57600, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
//uart 2: motherboard
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinConfigure(GPIO_PD6_U2RX);
GPIOPinConfigure(GPIO_PD7_U2TX);
GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7);
UARTConfigSetExpClk(UART2_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
//uart 3: endefector
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
GPIOPinConfigure(GPIO_PC6_U3RX);
GPIOPinConfigure(GPIO_PC7_U3TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);
UARTConfigSetExpClk(UART3_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
//initialize the rest of the GPIO sets we need and set up to output the one's that need to be output
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6); //actuator enable
GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_3); //actuator 1
GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_4); //actuator 2
//initialize the enable for the actuator
GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_6, GPIO_PIN_6);
//interrupt setups
IntMasterEnable();
UART2IntSetup();
The functions that are called for the interrupt itself are:
void UART2IntHandler()
{
uint8_t i;
UARTIntClear(UART2_BASE, UART_INT_RX);
UARTIntDisable(UART2_BASE, UART_INT_RX);
for(i = 0; i < 4; i++)
{
if(!(HWREG(UART2_BASE + UART_O_FR) & UART_FR_RXFE))//uartCharGetNonBlocking
{
uartRxBuf[i] = HWREG(UART2_BASE + UART_O_DR);
}
}
}
void UART2IntSetup()
{
IntEnable(INT_UART2);
UARTIntEnable(UART2_BASE, UART_INT_RX); //must enable before registering the function dynamically
UARTIntRegister(UART2_BASE, UART2IntHandler);
UARTFIFOLevelSet(UART2_BASE, UART_FIFO_TX1_8, UART_FIFO_RX7_8); //dont worry about the tx, it's unused
}
For testing purposes, what I'm doing to simulate the communication is to send the RX pin the data from the TX pin, connected across the wire. If it's relevant, this is the main and struct sending functions:
main()
{
struct arm_control_struct armData;
struct gripper_control_struct gripperData;
struct drill_Controls drillData;
receiveStruct receiveData;
[Loading up the armData struct to send it across to the RX pin, for testing purposes]
armData.reset = 1;
armData.wristUp = 0;
armData.wristDown = 0;
armData.wristClockWise = 0;
armData.wristCounterClockWise = 0;
armData.elbowUp = 0;
armData.elbowDown = 0;
armData.elbowClockWise = 0;
armData.elbowCounterClockWise = 0;
armData.actuatorForward = 0;
armData.actuatorReverse = 0;
armData.baseClockWise = 0;
armData.baseCounterClockWise = 0;
initHardware();
delay(DELAY);
send_struct(UART_ENDE, &drillData, INST_OTHER, DRILL_STRUCT_ID);
delay(DELAY);
void send_struct(uint32_t uart, void* my_struct, uint8_t instruction, uint8_t id)
{
uint8_t size;
uint8_t start_byte1 = 0x06;
uint8_t start_byte2 = 0x85;
switch(id)
{
case ARM_STRUCT_ID:
size = sizeof(*((struct arm_control_struct *)my_struct));
break;
case GRIPPER_STRUCT_ID:
size = sizeof(*((struct gripper_control_struct*)my_struct));
break;
case DRILL_STRUCT_ID:
size = sizeof(*((struct drill_Controls*)my_struct));
break;
}
uint8_t* address = (uint8_t*) my_struct; //pointer for use in sending the data.
uint8_t CS = size; //checksum
UARTCharPut(uart, start_byte1);
UARTCharPut(uart, start_byte2);
UARTCharPut(uart, id); //todo:Figure out where to put these in protocol
UARTCharPut(uart, instruction);
UARTCharPut(uart, size);
uint8_t i;
for(i = 0; i<size; i++)
{
CS^=*(address+i);
UARTCharPut(uart, (uint8_t)(*(address+i))); //sends the data values byte by byte that
//are found at the address variable and for each address that = (address + i) untilvi = size...in other words, the first data
//value in the struct and for all the following data values within it
}
UARTCharPut(uart, CS);
}