Hello,
I am trying to get data from gps and read it using STM32F4 mcu. I am using serial driver which reads bytes sent by gps and parse these bytes to get meaningful data. I am using sdRead() function to read data from serial buffer. I am using this function without any delay in tread so I assume I am updating function as fast as I can. However I am not able to get checksum properly as it fails everytime. Also data is not consistent as if I am loosing few bytes. I suspected this might be problem of buffer but then I increase size of buffer to 512 still having same problem.
I have check my parsing code on arduino and it works perfectly fine.
I am thinking of using uart driver but I suppose it does not have buffer implementation. Is there any solution to this problem. What is the difference when I call sdRead, sdAsychromousRead(), sdGet()?
Serial Driver Problem
Moderator: RoccoMarco
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Serial Driver Problem
Hi,
What version are you using? a bug has been recently fixed in the serial driver, update to 2.6.3.
Giovanni
What version are you using? a bug has been recently fixed in the serial driver, update to 2.6.3.
Giovanni
-
daniellpu9
- Posts: 5
- Joined: Tue Apr 29, 2014 2:49 pm
Re: Serial Driver Problem
Hi to everyone,
i have this code
I think that i have the mcuconf.h and hal.h well configurated. What i have wrong????... Plz help me!!!!!!!!!!!!!!
i have this code
Code: Select all
#include "ch.h"
#include "hal.h"
#include "test.h"
static void pwmpcb(PWMDriver *pwmp);
static void adccb(ADCDriver *adcp, adcsample_t *buffer, size_t n);
static void spicb(SPIDriver *spip);
int avg_ch1, avg_ch2;
int bla= 0x0400;
int dat1,dat2;
/* Total number of channels to be sampled by a single ADC operation.*/
#define ADC_GRP1_NUM_CHANNELS 1
/* Depth of the conversion buffer, channels are sampled four times each.*/
#define ADC_GRP1_BUF_DEPTH 4
/*
* ADC samples buffer.
*/
static adcsample_t samples[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH];
/*
* ADC conversion group.
* Mode: Linear buffer, 4 samples of 2 channels, SW triggered.
* Channels: IN11 (48 cycles sample time)
* Sensor (192 cycles sample time)
*/
static const ADCConversionGroup adcgrpcfg = {
FALSE,
ADC_GRP1_NUM_CHANNELS,
adccb,
NULL,
/* HW dependent part.*/
ADC_CR1_RES_1,
ADC_CR2_SWSTART,
ADC_SMPR1_SMP_AN11(ADC_SAMPLE_56),
0,
ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS),
0,
ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11)
};
/*
* SPI configuration structure.
* Maximum speed (12MHz), CPHA=1, CPOL=1, 16bits frames, MSb transmitted first.
* The slave select line is the pin GPIOA_SPI1NSS on the port GPIOA.
*/
static const SPIConfig spicfg = {
spicb,
/* HW dependent part.*/
GPIOB,
12,
SPI_CR1_DFF | SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_2 | SPI_CR1_BR_0
//SPI_CR1_CPHA | SPI_CR1_CPOL |SPI_CR1_BR_2
};
/*
* ADC end conversion callback.
* The PWM channels are reprogrammed using the latest ADC samples.
* The latest samples are transmitted into a single SPI transaction.
*/
void adccb(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
(void) buffer; (void) n;
/* Note, only in the ADC_COMPLETE state because the ADC driver fires an
intermediate callback when the buffer is half full.*/
if (adcp->state == ADC_COMPLETE) {
/* Calculates the average values from the ADC samples.*/
avg_ch1 = (samples[0] + samples[1] + samples[2] + samples[3]) / 4;
}
}
/*
* SPI end transfer callback.
*/
static void spicb(SPIDriver *spip) {
/* On transfer end just releases the slave select line.*/
chSysLockFromIsr();
spiUnselectI(spip);
chSysUnlockFromIsr();
}
/*
* This is a periodic thread that does absolutely nothing except flashing
* a LED.
*/
static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {
(void)arg;
chRegSetThreadName("ADC");
while (TRUE) {
palSetPad(GPIOD, GPIOD_LED3); /* Orange. */
chThdSleepMilliseconds(20);
chSysLockFromIsr();
adcStartConversionI(&ADCD1, &adcgrpcfg, samples, ADC_GRP1_BUF_DEPTH);
chSysUnlockFromIsr();
palClearPad(GPIOD, GPIOD_LED3); /* Orange. */
chThdSleepMilliseconds(20);
}
}
static WORKING_AREA(waThread2, 128);
static msg_t Thread2(void *arg) {
(void)arg;
chRegSetThreadName("SPI");
while (TRUE) {
palSetPad(GPIOD, GPIOD_LED4); // Green.
chThdSleepMilliseconds(20);
chSysLockFromIsr();
// SPI slave selection and transmission start.
spiSelectI(&SPID2);
spiStartSendI(&SPID2, 1, &bla);
chThdSleepMilliseconds(1);
spiStartReceiveI(&SPID2, 1, &avg_ch2);
chThdSleepMilliseconds(1);
dat1 = avg_ch2 & 0xFF;
dat2 = (avg_ch2 & 0xFF00) >>8;
chSysUnlockFromIsr();
palClearPad(GPIOD, GPIOD_LED4); // Green.
chThdSleepMilliseconds(20);
}
}
static WORKING_AREA(waThread3, 128);
static msg_t Thread3(void *arg) {
(void)arg;
chRegSetThreadName("GPS");
while (TRUE) {
chSysLockFromIsr();
palSetPad(GPIOD, GPIOD_LED5); // Red.
chThdSleepMilliseconds(2000);
palClearPad(GPIOD, GPIOD_LED5); // Red .
chThdSleepMilliseconds(2000);
chSysUnlockFromIsr();
}
}
/*
* Application entry point.
*/
int main(void) {
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
chSysInit();
/*
* Activates the serial driver 1 using the driver default configuration.
* PA9(TX) and PA10(RX) are routed to USART1.
*/
sdStart(&SD1, NULL);
palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(7));
palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(7));
/*
* Activates the serial driver 2 using the driver default configuration.
* PA2(TX) and PA3(RX) are routed to USART2.
*/
sdStart(&SD2, NULL);
palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7));
palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7));
/*
* Initializes the SPI driver 2. The SPI2 signals are routed as follow:
* PB12 - NSS.
* PB13 - SCK.
* PB14 - MISO.
* PB15 - MOSI.
*/
spiStart(&SPID2, &spicfg);
palSetPad(GPIOB, 12);
palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL |
PAL_STM32_OSPEED_HIGHEST); /* NSS. */
palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(5) |
PAL_STM32_OSPEED_HIGHEST); /* SCK. */
palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(5)); /* MISO. */
palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(5) |
PAL_STM32_OSPEED_HIGHEST); /* MOSI. */
/*
* Initializes the ADC driver 1 and enable the thermal sensor.
* The pin PC0 on the port GPIOC is programmed as analog input.
*/
adcStart(&ADCD1, NULL);
palSetPadMode(GPIOC, 1, PAL_MODE_INPUT_ANALOG);
/*
* Creates the example thread.
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, NULL);
chThdCreateStatic(waThread3, sizeof(waThread3), NORMALPRIO, Thread3, NULL);
while (TRUE)
{
//sdPut(&SD2, avg_ch1);
//sdPut(&SD2, dat1);
//sdPut(&SD2, dat2);
chnWrite(&SD1,(const uint8_t *)"Bla\r\n", 14);
chnWrite(&SD2,(const uint8_t *)"Bla\r\n", 14);
chThdSleepMilliseconds(1000);
}
}I think that i have the mcuconf.h and hal.h well configurated. What i have wrong????... Plz help me!!!!!!!!!!!!!!
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Serial Driver Problem
Hi,
There are several errors, for example:
- FromIsr() functions not into an ISR.
- An "I" function not within lock/unlock.
I recommend reading the "kernel concepts" section in the documentation. You should also activate the state checker in chconf.h, it is able to detect this kind of errors.
Giovanni
There are several errors, for example:
- FromIsr() functions not into an ISR.
- An "I" function not within lock/unlock.
I recommend reading the "kernel concepts" section in the documentation. You should also activate the state checker in chconf.h, it is able to detect this kind of errors.
Giovanni
-
daniellpu9
- Posts: 5
- Joined: Tue Apr 29, 2014 2:49 pm
Re: Serial Driver Problem
But i use that function FROMISR() because in the STM32F4 example you uses that a lot... i read the documentation about that function and i dont understood >/
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times