I’m trying to set up a bluetooth connection in native code, and I can’t seem to get the reading to work properly. Writing to bluetooth from native code is working, and both reading and writing are working from c# so the connections on the board are correct. I’m setting up the bluetooth connection in c#, then using the RLP method EnableInterruptInputMode to set up an interrupt, which is being called but I can’t figure out where to read the value of the received byte. I’m creating the connection over COM1 by creating the interrupt on pin 20 (as per page 13 of http://www.ghielectronics.com/downloads/USBizi/USBizi_User_Manual.pdf), and trying to read from U1RBR to get the data (as well as U0RBR since page 28 of that same document shows that COM1 uses UART0, but I always get zeros from each register.
Here’s the useful segments of the code I’m using:
In C# code:
bluetooth = new SerialPort("COM1", BAUD_RATE, Parity.None, 8, StopBits.One);
//bluetooth.DataReceived += new SerialDataReceivedEventHandler(bluetooth_DataReceived);
bluetooth.Open();
int result = rlp_StartBluetooth.Invoke();
Debug.Print("StartBluetooth() returned " + result.ToString());
Thread.Sleep(Timeout.Infinite);
Debug("Start of bluetoothReceiveISR");
volatile char c;
c = U1RBR;
Debug("U1RBR:");
Debug_int(c);
c = U0RBR;
Debug("U0RBR: " );
Debug_int(c);
VICVectAddr = 0; // Acknowledge Interrupt
Any ideas why U0RBR and U1RBR are both always 0? Do I need to set anything else to have them filled with data, or am I reading from the wrong place? Thanks!
I have no direct input, but a question. Why are you going to this level when you can deal with serial IO wholly within C# managed code? RLP is good for some things, but I am not sure you need it in this scenario.
My plan is to use a Fez Domino to get analog input, do some data analysis and then send it over bluetooth to a computer where an application will run and be controlled by the the updates coming from bluetooth. I ran some quick tests using c# and was able to get these updates at an alright, but not great speed. There will also be some reasonably heavy data processing that I’ll definitely want to do in native code, and I figured I’d try to pretty much write everything in native
I’m now opening the connection entirely in C code, but I’m still unable to actually read the data that is being received. I have tried registering an interrupt function one of two ways:
Registering the function using RLPext->GPIO.EnableInterruptInputMode(). Here I get into the interrupt function, but every time U0IIR is 193 (1100 0001), which seems to mean that I have FIFO Enabled, but no interrupt.
Declaring an interrupt function as “attribute ((interrupt (“IRQ”)))” and setting it in the VICVectAddr6 register. When I do this I don’t actually see the output from the interrupt function being called, but Visual Studio hangs everytime I stop my application after sending the microcontroller a bluetooth message, so it seems like something is happening here but I don’t know what.
I’m able to send successfully over bluetooth, and in the first setup I see the debug output coming when (and only when) I send the device a message. Any ideas why I’m still not able to see whats being received? Here’s all the code that I’m currently using:
#define RX_INTERRUPT_PIN 20
#define VIC_CHAN_NUM_UART0 6
#define VIC_CHAN_TO_MASK(vctm_chan_num__) (1UL<<vctm_chan_num__)
// FIFO Control Register bit definitions
#define UFCR_FIFO_ENABLE (1 << 0) // FIFO Enable
#define UFCR_RX_FIFO_RESET (1 << 1) // Reset Receive FIFO
#define UFCR_TX_FIFO_RESET (1 << 2) // Reset Transmit FIFO
#define UFCR_FIFO_TRIG1 (0 << 6) // Trigger @ 1 character in FIFO
#define UFCR_FIFO_TRIG4 (1 << 6) // Trigger @ 4 characters in FIFO
#define UFCR_FIFO_TRIG8 (2 << 6) // Trigger @ 8 characters in FIFO
#define UFCR_FIFO_TRIG14 (3 << 6) // Trigger @ 14 characters in FIFO
// Line Control Register bit definitions
#define ULCR_CHAR_5 (0 << 0) // 5-bit character length
#define ULCR_CHAR_6 (1 << 0) // 6-bit character length
#define ULCR_CHAR_7 (2 << 0) // 7-bit character length
#define ULCR_CHAR_8 (3 << 0) // 8-bit character length
#define ULCR_STOP_1 (0 << 2) // 1 stop bit
#define ULCR_STOP_2 (1 << 2) // 2 stop bits
#define ULCR_PAR_NO (0 << 3) // No Parity
#define ULCR_PAR_ODD (1 << 3) // Odd Parity
#define ULCR_PAR_EVEN (3 << 3) // Even Parity
#define ULCR_PAR_MARK (5 << 3) // MARK "1" Parity
#define ULCR_PAR_SPACE (7 << 3) // SPACE "0" Paruty
#define ULCR_BREAK_ENABLE (1 << 6) // Output BREAK line condition
#define ULCR_DLAB_ENABLE (1 << 7) // Enable Divisor Latch Access
#define UART_8N1 (uint8_t)(ULCR_CHAR_8 + ULCR_PAR_NO + ULCR_STOP_1)
#define UART_FIFO_1 (uint8_t)(UFCR_FIFO_ENABLE + UFCR_FIFO_TRIG1)
#define UIER_RBR (1UL << 0) // (UIER_ERBFI) Enable Receive Data Available Interrupt
void interruptHandler()
{
Debug("Start of bluetoothReceiveISR");
volatile char dummy;
volatile char IIR;
IIR = U0IIR;
Debug("U0IIR:");
Debug_int(IIR);
//while (((IIR = U0IIR) & 0x01) == 0) {
uart_interrupt_count++;
switch (IIR & 0x0F) {
case 0x06: /* Receive Line Status */
Debug("receive line status");
dummy = U0LSR; /* Just clear the interrupt source */
break;
case 0x04: /* Receive Data Available */
Debug("Receive dat available");
case 0x0C: /* Character Time-Out */
Debug("Character timeout");
dummy = U0RBR;
break;
case 0x02: /* THRE Interrupt */
Debug("THRE interrupt");
break;
case 0x00: /* Modem Interrupt */
Debug("Modem interrupt");
dummy = U1MSR; /* Just clear the interrupt source */
break;
default:
break;
}
//}
VICVectAddr = 0;
}
/*
function used to register an interrupt using RLPext->GPIO.EnableInterruptInputMode()
*/
void bluetoothReceiveISR( unsigned int Pin, unsigned int PinState, void* Param )
{
interruptHandler();
}
/*
interrupt function to be registered in the Vectored Interrupt Controller
*/
__attribute__ ((interrupt ("IRQ")))
void uart0ISR (void)
{
interruptHandler();
}
int USE_RLP_FOR_INTERRUPT = 0;
/*
This gets called by c# to open the connection
*/
void openBluetoothConnection()
{
int mode = UART_8N1; //8bits/char, no parity, 1 stop bit
int fmode = UART_FIFO_1; //fifo enable, trigger interrupt every char
PINSEL0 |= 0x50; //Enabled TxD0 and RxD0
PINMODE0 |= 0xA0; //set proper pin mode for rx and tx registers(no resistor enabled)
U0IER = 0; //disable all interrupts
U0IIR; // clear interrupt ID
U0RBR; // clear receive register
U0LSR; // clear line status register
// set the baudrate
U0LCR = ULCR_DLAB_ENABLE; // select divisor latches
//these are copied from what happens when the connection is opened in C# code, for baud rate 9600
U0DLL = 74;
U0DLM = 0;
U0FDR = 199;
U0LCR = (mode & ~ULCR_DLAB_ENABLE); //set mode(#bits, parity?, #stop bits), disable dlab
U0FCR = fmode; //set trigger level, enable fifo
if(USE_RLP_FOR_INTERRUPT)
{
RLP_InterruptInputPinArgs pinArgs = {RLP_FALSE, RLP_GPIO_INT_EDGE_HIGH, RLP_GPIO_RESISTOR_DISABLED};
int result = RLPext->GPIO.EnableInterruptInputMode(RX_INTERRUPT_PIN, &pinArgs, bluetoothReceiveISR, 0);
Debug("Result of RLPext->GPIO.EnableInterruptInputMode:");
Debug_int(result);
}
else
{
//initialize the interrupt vector
VICIntSelect &= ~VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART0); //set interrupt type irq
VICIntEnClr = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART0); //clear bit from the interrupt enable register
VICVectAddr6 = (uint32_t)uart0ISR; //set the actual interrupt
VICVectCntl6 = 0xF; //set priority to highest(15)
VICIntEnable = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART0); //enable the interrupt
}
U0IER = UIER_RBR; //enable interrupts on rbr
}