CH340 handshaking using libusb - libusb

Does anyone know how to read CTS pin of CH340 using libusb_control_transfer? I can write to RTS using following code:
libusb_control_transfer( handle, // libusb_device_handle * dev_handle
CTRL_OUT, // uint8_t bmRequestType
0xA4, // uint8_t bRequest
1<<6, // uint16_t wValue
0, // uint16_t wIndex
NULL, // unsigned char *data
0, // uint16_t wLength
1000); // unsigned int timeout
So I think it might be possible to do the same to read state of CTS pin?

Thanks to kernel driver source code:
libusb_control_transfer( handle,
CTRL_IN,
0x95,
0x0706,
0,
&data[0],
2,
1000);

Related

how to send 32bits frame at once from efm32 controller

I am trying to send 32bits at once from my USART in my efm32 controller.
I improvised the following way where i define usart frame register first 4 bitfield as 13(to have 16 bit frame as shown in manual bellow)using
USART0->FRAME=USART0->FRAME&(0xFFFFFFF<<4) //leaving all bits except the first 4
USART0->FRAME=USART0->FRAME|(0b1010)
Using the TXDOUBLE register i put the first 16 variable in 0-15 place and second 16bit variable at 16-31 places using(as shown in the manual bellow)
USART0->TXDOUBLE=(USART0->TXDOUBLE)&(0xFFFF<<16)//zeros at b15-b0
USART0->TXDOUBLE=USART0->TXDOUBLE|TxBuffer[0]; //setting b15-b0
USART0->TXDOUBLE=(USART0->TXDOUBLE)&(0xFFFF)//zeros at b31-b16
USART0->TXDOUBLE=USART0->TXDOUBLE|(TxBuffer[1]<<16); //setting b31-b16
Is this a valid method?
Did i implemented correctly the bitfield value setting?
The full code is shown bellow.
Thanks.
enter image description here
#define TX_BUFFER_SIZE 2
#define RX_BUFFER_SIZE TX_BUFFER_SIZE
//W/R=0 write and update channeL0 all1 data dont cate
uint16_t TxBuffer[TX_BUFFER_SIZE] = {0b0000001100001111,0b1111111111110000};
uint32_t TxBufferIndex = 0;
uint8_t RxBuffer[RX_BUFFER_SIZE] = {0};
uint32_t RxBufferIndex = 0;
volatile uint32_t msTicks; /* counts 1ms timeTicks */
void Delay(uint32_t dlyTicks);
void SysTick_Handler(void)
{
msTicks++; /* increment counter necessary in Delay()*/
}
void Delay(uint32_t dlyTicks)
{
uint32_t curTicks;
curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks) ;
}
int main(void)
{
// Initialize chip
CHIP_Init();
if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) {
while (1) ;
}
CMU_ClockEnable(cmuClock_GPIO, true);
CMU_ClockEnable(cmuClock_USART0, true);
GPIO_PinModeSet(gpioPortE, 12, gpioModePushPull, 0); // US1_CLK is push pull
GPIO_PinModeSet(gpioPortA, 2, gpioModePushPull, 1); // US1_CS is push pull
GPIO_PinModeSet(gpioPortE, 10, gpioModePushPull, 0); // US1_TX (MOSI) is push pull
GPIO_PinModeSet(gpioPortE, 11, gpioModeInput, 1); // US1_RX (MISO) is input
GPIO_PinModeSet(gpioPortA, 3, gpioModePushPull, 0); // LDAC
GPIO_PinModeSet(gpioPortA, 1, gpioModePushPull, 1); // CLR
///////////////////////////////////////////////////////
// Start with default config, then modify as necessary
USART_InitSync_TypeDef config = USART_INITSYNC_DEFAULT;
config.master = true; // master mode
config.baudrate = 1000000; // CLK freq is 1 MHz
config.autoCsEnable = false; // CS pin controlled by hardware, not firmware
config.clockMode = usartClockMode0; // clock idle low, sample on rising/first edge
config.msbf = true; // send MSB first
USART_InitSync(USART0, &config);
USART0->ROUTE = USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC0;
///////////////////////////////////////////
USART_Enable(USART0, usartEnable);
TxBufferIndex = 0;
USART0->IEN = USART_IEN_TXC; //enable TXC interrupt flag
USART0->FRAME=USART0->FRAME&(0xFFFFFFF<<4) //leaving all bits except the first 4
USART0->FRAME=USART0->FRAME|(0b1010)
while(1)
{
Delay(1);
GPIO_PinOutClear(gpioPortA,2);
USART0->TXDOUBLE=(USART0->TXDOUBLE)&(0xFFFF<<16)//zeros at b15-b0
USART0->TXDOUBLE=USART0->TXDOUBLE|TxBuffer[0]; //setting b15-b0
USART0->TXDOUBLE=(USART0->TXDOUBLE)&(0xFFFF)//zeros at b31-b16
USART0->TXDOUBLE=USART0->TXDOUBLE|(TxBuffer[1]<<16); //setting b31-b16
while( !(USART0->STATUS & USART_STATUS_TXC) ); //wait TILL TXC goes high
GPIO_PinOutSet(gpioPortA,2);
Delay(2000);
}
Here's some code how it could work. It's a shot into the dark as I've never used an EFM32 and had no way of compiling or otherwise verifying the code. (I don't understand the purpose of USART0->ROUTE so I just copied it over.)
uint8_t TxBuffer[] = { 0b00000011, 0b00001111, 0b11111111, 0b11110000 };
int main(void)
{
...
CMU_ClockEnable(cmuClock_GPIO, true);
CMU_ClockEnable(cmuClock_USART0, true);
GPIO_PinModeSet(gpioPortE, 12, gpioModePushPull, 0); // US1_CLK is push pull
GPIO_PinModeSet(gpioPortA, 2, gpioModePushPull, 1); // US1_CS is push pull
GPIO_PinModeSet(gpioPortE, 10, gpioModePushPull, 0); // US1_TX (MOSI) is push pull
GPIO_PinModeSet(gpioPortE, 11, gpioModeInput, 1); // US1_RX (MISO) is input
...
USART_InitSync_TypeDef config = USART_INITSYNC_DEFAULT;
config.master = true; // master mode
config.baudrate = 1000000; // CLK freq is 1 MHz
config.databits = usartDatabits8;
config.autoCsEnable = false; // CS pin controlled by hardware, not firmware
config.clockMode = usartClockMode0; // clock idle low, sample on rising/first edge
config.msbf = true; // send MSB first
USART_InitSync(USART0, &config);
USART0->ROUTE = USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC0;
USART_Enable(USART0, usartEnable);
while (1)
{
Transmit(TxBuffer, sizeof(TxBuffer));
Delay(2000);
}
}
void Transmit(const uint8_t* buf, int len)
{
// Pull CS (SYNC) low
GPIO_PinOutClear(gpioPortA, 2);
for (int i = 0; i < len; i++)
{
// Wait until FIFO is (half) empty
while( !(USART0->STATUS & USART_STATUS_TXBL) );
// Put next byte into FIFO
USART0->TXDATA = buf[i];
}
// Wait until transmissiob is complete
while( !(USART0->STATUS & USART_STATUS_TXC) );
// Pull CS (SYNC) high
GPIO_PinOutSet(gpioPortA, 2);
}
The USART has a three stage queue (two FIFO registers and a shift register). So by checking the TXBL flag, it's possibly to put new bytes into the queue while the previous bytes are still transmitting. That way it's easy to keep the queue filled such that the USART does not need to pause between bytes.
At the end, the TXC flag is checked to ensure that all bytes in the queue have been fully transmitted before CS/SYNC is pull high.

STM32L072CZTx mpu6050 i2c No ACK after some successfull transmitting

i made a customboard with a MPU-6050 & STM32L072CZTx on it.
My problem is, that the MPU-6050 doesn't ack after some successfull transmision.
I have two 4,7k pull-ups on SCL and SDA.
Restarting the MCU doesn't fix it.
I have to unplug the power to get the MPU to ACK again for some transmision.
I am using STM32 HAL and added 2 images for clarification.
What i tried:
Replaced MPU6050
lowered I2C frequenzy
much more...
Thanks for your help.
HAL_StatusTypeDef writeBytes(uint8_t deviceAdd, uint8_t regAdd, uint8_t *data, uint8_t size)
{
uint8_t buffer[size + 1];
buffer[0] = regAdd;
memcpy((buffer + 1), data, size);
return HAL_I2C_Master_Transmit(&hi2c1, deviceAdd << 1, buffer, size + 1, I2C_TIMEOUT);
}
HAL_StatusTypeDef readBytes(uint8_t deviceAdd, uint8_t regAdd, uint8_t *data, uint8_t size)
{
return HAL_I2C_Mem_Read(&hi2c1, (uint16_t)(deviceAdd << 1), (uint16_t)regAdd, I2C_MEMADD_SIZE_8BIT, data, size, I2C_TIMEOUT);
}
Oscilloscope
MPU6050 schematic

GPS interface with 8051 UC

I am trying to extract data of Lat and Long sent by GPS module to the 8051uC.
GPS received data looks like:
$GPRMC,062637.000,A,2253.49272,N,07258.83129,E,,,270212,,,A*6970212,0.1,W,A*12
I need to write in the LCD the LAT and LONG,
I started the code by MikriC compiler from an example but sounds it is incompleted
char uart_rd;
sbit LCD_RS at P2_0_bit;
sbit LCD_EN at P2_1_bit;
sbit LCD_D4 at P2_2_bit;
sbit LCD_D5 at P2_3_bit;
sbit LCD_D6 at P2_4_bit;
sbit LCD_D7 at P2_5_bit;
char idata info[70];
char test[]="$GPGGA";
unsigned int check=0,i;
unsigned char a;
int j;
void main() {
Lcd_Init();
UART1_Init(4800); // Initialize UART module at 4800 bps,
// receiver enabled
//frame size 8 bits
//1 STOP bit
//parity mode disabled
//disabled automatic address recognition
Delay_ms(100); // Wait for UART module to stabilize
while (1) {
if (UART1_Data_Ready() == 1) { // if data is received
UART1_Read_Text(info, "$GPGGA", 10); // reads text until '$GPRMC' is found
LCD_Out(1,1,info);
} Delay_ms(1000);
}
}

InterruptAttach fails on am3352x irq number 97 for bank 0B

I am trying to attach an IRQ handler to a gpio bank 0 i.e 0B irq no 97.
At the present moment, my implementation returns with -1. What am I doing wrong? It would be a very simple issue to implement.
#include <stdio.h>
#include <unistd.h>
#include "gpio.h"
#include <sys/neutrino.h>
#include "interrupt.h"
volatile unsigned int gpio0_irq_count;
static const struct sigevent * gpio0_irq_handler (void *gpio, int id){
gpio0_irq_count++;
return NULL;
}
int main(){
int ret;
unsigned long count=0;
ret = InterruptAttach(97, gpio0_irq_handler, NULL,0,_NTO_INTR_FLAGS_TRK_MSK);
printf("%s: Registering handler for irq %d result = %d\n",__func__ , 97, ret);
if (ret)
return -1;
while(1){
printf("%s:[%lu] : gpio0_irq_count = %d\n", __func__, count++, gpio0_irq_count);
sleep(2);
}
}
The erroneous output is:
main: Registering handler for irq 97 result = -1
After much back and forth with QNX, it turns out that a process requesting InterruptAttach() or InterruptAttach_r() needs elevated permissions acquired through
ThreadCtl( _NTO_TCTL_IO, 0 );
Once that is executed the API's work. However, one must still configure the gpio registers to actually fire the interrupt.
GPIO_OE
GPIO_STATUS
GPIO_STATUS_SET
GPIO_CTRL
GPIO_RISINGDETECT

iOS: send customized uint8 array

I'm trying to make an app that communicate iPhone with another hardware using dock to RS232 wire (I bought from RedPark). I'm also using the library provided by redpark. I made a simple code at beginning, it worked fine.
UInt8 infoCmd[5] = {0x3E,0x3E,0x05,0x80,0xff};
[rscMgr write:infoCmd Length:5];
Then I want to add more command to it, so I create a method that returns different combinations of command I need.
- (UInt8 *)requestCommand:(int)commandName{
UInt8 * command;
if (commandName == DATADUMP) {
command=[Communication buildDataDump];
}
if (commandName == GETSERIALINFO) {
command=[Communication buildGetSerailInfo];
}
return command;
}
+ (UInt8 *)buildGetSerailInfo{
UInt8 *command = malloc(sizeof(UInt8)*5);
command[0]=SYN;
command[1]=SYN;
command[2]=ENQ;
command[3]=GETSERIALINFO;
//command[4] = {SYN, SYN, ENQ, GETSERIALINFO};
return command;
}
The thing is, some of my commands includes data that can be 200 bytes long. How can I create an UInt8 array that is easier for me to add bytes?
I'm new to programming, please explain to me in detail. Thank you a lot in advance.
Actually you will just send data, row byte over the wire. I do something similar in one project (not wire, but RS232 commands over TCP/IP), and it becomes quite simple, if you use an NSMutableData instance.
A snippet from my code:
static u_int8_t codeTable[] = { 0x1b, 0x74, 0x10 };
static u_int8_t charSet[] = { 0x1b, 0x52, 0x10 };
static u_int8_t formatOff[] = { 0x1b, 0x21, 0x00 };
static u_int8_t reverseOn[] = { 0x1d, 0x42, 0x01 };
static u_int8_t reverseOff[]= { 0x1d, 0x42, 0x00 };
static u_int8_t paperCut[] = { 0x1d, 0x56, 0x0 };
NSMutableData *mdata = [NSMutableData dataWithBytes:&formatOff length:sizeof(formatOff)];
[mdata appendBytes:&formatOff length:sizeof(formatOff)];
[mdata appendBytes:&reverseOff length:sizeof(reverseOff)];
[mdata appendData: [NSData dataWithBytes: &codeTable length:sizeof(codeTable)]];
[mdata appendData: [NSData dataWithBytes: &charSet length:sizeof(charSet)]];
As you see, I am just appending the data byte by byte.