/* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. ChibiOS/RT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. ChibiOS/RT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "ch.h" #include "hal.h" #include "test.h" #include "settings.h" /* * LED blinker thread, times are in milliseconds. */ static WORKING_AREA(blinker_wa, 128); static msg_t blinker_thread(void *p) { (void)p; while (TRUE) { palClearPad(IOPORT3, GPIOC_LED); chThdSleepMilliseconds(500); palSetPad(IOPORT3, GPIOC_LED); chThdSleepMilliseconds(500); } return 0; } #if CH_HAL_USE_ADC static adcsample_t samples[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH]; static Thread *adctp; /* * ADC continuous conversion thread. */ size_t nx = 0, ny = 0; static void adccallback(adcsample_t *buffer, size_t n) { if (samples == buffer) { nx += n; } else { ny += n; } } static WORKING_AREA(adc_continuous_wa, 256); static msg_t adc_continuous_thread(void *p){ (void)p; palSetGroupMode(IOPORT3, PAL_PORT_BIT(0) | PAL_PORT_BIT(1), PAL_MODE_INPUT_ANALOG); adcStart(&ADCD1, &adccfg); adcStartConversion(&ADCD1, &adcgrpcfg, samples, ADC_GRP1_BUF_DEPTH, adccallback); adcWaitConversion(&ADCD1, TIME_INFINITE); adcStop(&ADCD1); return 0; } #endif /* CH_HAL_USE_ADC */ #if CH_HAL_USE_CAN static Thread *canrtp; static Thread *canttp; static WORKING_AREA(can_rx_wa, 256); static msg_t can_rx(void *p) { EventListener el; CANRxFrame rxmsg; (void)p; chEvtRegister(&CAND1.cd_rxfull_event, &el, 0); while(!chThdShouldTerminate()) { if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0) continue; while (canReceive(&CAND1, &rxmsg, TIME_IMMEDIATE) == RDY_OK) { /* Process message.*/ palTogglePad(IOPORT3, GPIOC_LED); } } chEvtUnregister(&CAND1.cd_rxfull_event, &el); return 0; } static WORKING_AREA(can_tx_wa, 256); static msg_t can_tx(void * p) { CANTxFrame txmsg; (void)p; txmsg.cf_IDE = CAN_IDE_EXT; txmsg.cf_EID = 0x01234567; txmsg.cf_RTR = CAN_RTR_DATA; txmsg.cf_DLC = 8; txmsg.cf_data32[0] = 0x55AA55AA; txmsg.cf_data32[1] = 0x00FF00FF; while (!chThdShouldTerminate()) { canTransmit(&CAND1, &txmsg, MS2ST(100)); /* chThdSleepMilliseconds(5);*/ } return 0; } #endif /* CH_HAL_USE_CAN */ #if CH_HAL_USE_SPI static uint8_t txbuf[512]; static uint8_t rxbuf[512]; static Thread *spitp; /* * Maximum speed SPI continuous loopback thread. */ static WORKING_AREA(spi_loopback_wa, 256); static msg_t spi_loopback_thread(void *p){ (void)p; palSetPadMode(IOPORT1, GPIOA_SPI1NSS, PAL_MODE_OUTPUT_PUSHPULL); palSetPad(IOPORT1, GPIOA_SPI1NSS); spiStart(&SPID1, &spicfg); while (!chThdShouldTerminate()) { spiSelect(&SPID1); spiExchange(&SPID1, 512, txbuf, rxbuf); spiUnselect(&SPID1); } spiStop(&SPID1); return 0; } #endif /* CH_HAL_USE_SPI */ /* * Entry point, note, the main() function is already a thread in the system * on entry. */ int main(int argc, char **argv) { unsigned i; (void)argc; (void)argv; (void)i; /* * Activates the serial driver 2 using the driver default configuration. */ sdStart(&SD2, NULL); /* * Creates the blinker thread. */ chThdCreateStatic(blinker_wa, sizeof(blinker_wa), NORMALPRIO + 10, blinker_thread, NULL); #if CH_HAL_USE_ADC /* * Creates the ADC continuous conversion test thread. */ adctp = chThdCreateStatic(adc_continuous_wa, sizeof(adc_continuous_wa), NORMALPRIO + 9, adc_continuous_thread, NULL); #endif #if CH_HAL_USE_CAN canStart(&CAND1, &cancfg); canrtp = chThdCreateStatic(can_rx_wa, sizeof(can_rx_wa), NORMALPRIO + 7, can_rx, NULL); canttp = chThdCreateStatic(can_tx_wa, sizeof(can_tx_wa), NORMALPRIO + 7, can_tx, NULL); #endif #if CH_HAL_USE_SPI /* * Creates the SPI loopback test thread. */ for (i = 0; i < sizeof(txbuf); i++) txbuf[i] = (uint8_t)i; spitp = chThdCreateStatic(spi_loopback_wa, sizeof(spi_loopback_wa), NORMALPRIO + 8, spi_loopback_thread, NULL); #endif /* * Normal main() thread activity, in this demo it does nothing except * sleeping in a loop and check the button state. */ while (TRUE) { if (palReadPad(IOPORT1, GPIOA_BUTTON)) { TestThread(&SD2); #if CH_HAL_USE_ADC adcStopConversion(&ADCD1); chThdWait(adctp); #endif #if CH_HAL_USE_CAN chThdTerminate(canttp); chThdWait(canttp); chThdTerminate(canrtp); chThdWait(canrtp); #endif #if CH_HAL_USE_SPI chThdTerminate(spitp); chThdWait(spitp); #endif chThdSleepMilliseconds(500); TestThread(&SD2); chThdSleepMilliseconds(500); chSysHalt(); } chThdSleepMilliseconds(500); } return 0; }