/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
#include <stdio.h>
#include <string.h>
#include "ch.h"
#include "hal.h"
//#include "test.h"
#include "shell.h"
#include "evtimer.h"
#include "chprintf.h"
#if (HAL_USE_SERIAL_USB == TRUE)
#include "usbcfg.h"
#endif
#include "useAdc.h"
#include "shellCmds.h"
static MUTEX_DECL(mutexDisplay);
/*===========================================================================*/
/* Command line related. */
/*===========================================================================*/
#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(2048)
#define TEST_WA_SIZE THD_WORKING_AREA_SIZE(256)
static const ShellConfig shell_cfg1 = {
#if (HAL_USE_SERIAL_USB == TRUE)
(BaseSequentialStream *)&SDU1,
#else
(BaseSequentialStream *)&SD1,
#endif
shellCommands
};
////////
// end of shell stuff
uint16_t sampIndex;
void setDriveA(uint8_t bit)
{
if(bit)
{
palSetPad(GPIOA, GPIOA_A1);
palClearPad(GPIOA, GPIOA_A2);
}
else
{
palClearPad(GPIOA, GPIOA_A1);
palSetPad(GPIOA, GPIOA_A2);
}
}
void setDriveB(uint8_t bit)
{
if(bit)
{
palSetPad(GPIOA, GPIOA_B1);
palClearPad(GPIOA, GPIOA_B2);
}
else
{
palClearPad(GPIOA, GPIOA_B1);
palSetPad(GPIOA, GPIOA_B2);
}
}
volatile int origin = 0;;
volatile int target = 630;
volatile int count = 0;
static THD_WORKING_AREA(waThread1, 512);
static msg_t Thread1(void *arg) {
(void) arg;
unsigned const fast=10 ;
unsigned const slow = 40;
unsigned const range = slow-fast;
unsigned del = fast;
int step = 1;
chRegSetThreadName("Step");
while (TRUE) {
switch (count % 4)
{
case 0: setDriveA(1); setDriveB(0); break;
case 1: setDriveA(1); setDriveB(1); break;
case 2: setDriveA(0); setDriveB(1); break;
case 3: setDriveA(0); setDriveB(0); break;
}
chThdSleep(del);
count = count + step;
// all this calculates minimum distance from
// target or origin
int d1= count-origin;
if(d1<0) d1 = -d1;
int d2= count-target;
if(d2<0) d2 = -d2;
// finally, minimum distance
int dist = d1<d2 ? d1 : d2;
del = fast ;
if(dist < range) // inside lower bound of distance
{
del = slow-dist;
}
if(count < target ) { step = 1; }
if(count > target ) { step =-1; }
if(count == target) { step = 0; }
}
return 0;
}
/*
* Command Shell Thread
*/
static THD_WORKING_AREA(waThread2, 512);
static msg_t Thread2(void *arg) {
thread_t *shelltp = NULL;
chRegSetThreadName("Shell ");
/*
* in this demo it just performs
* a shell respawn upon its termination.
*/
while (true) {
if (!shelltp) {
#if (HAL_USE_SERIAL_USB == TRUE)
if (SDU1.config->usbp->state == USB_ACTIVE) {
/* Spawns a new shell.*/
shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE, "shell", NORMALPRIO, shellThread, (void *) &shell_cfg1);
}
#else
shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE, "shell", NORMALPRIO, shellThread, (void *) &shell_cfg1);
#endif
}
else {
/* If the previous shell exited.*/
if (chThdTerminatedX(shelltp)) {
/* Recovers memory of the previous shell.*/
chThdRelease(shelltp);
shelltp = NULL;
}
}
chThdSleepMilliseconds(500);
}
return MSG_OK;
}
/*
* Application entry point.
*/
int main(void) {
// struct EventListener el0, el1;
/*
* 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();
#if (HAL_USE_SERIAL_USB == TRUE)
/*
* Initializes a serial-over-USB CDC driver.
*/
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg);
#if HAL_USE_USB_DUAL_CDC == TRUE
sduObjectInit(&SDU2);
sduStart(&SDU2, &serusbcfg2);
#endif
/*
* Activates the USB driver and then the USB bus pull-up on D+.
* Note, a delay is inserted in order to not have to disconnect the cable
* after a reset.
*/
usbDisconnectBus(serusbcfg.usbp);
chThdSleepMilliseconds(1000);
usbStart(serusbcfg.usbp, &usbcfg);
usbConnectBus(serusbcfg.usbp);
#else
/*
* Initializes serial port.
*/
sdStart(&SD2, NULL);
#endif /* HAL_USE_SERIAL_USB */
useAdc();
/*
* Shell manager initialization.
*/
shellInit();
/*
* Creates the PLL thread
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, NULL);
/* start the SPI hardware for display */
while(1)
{
// read the dial
adcSample();
origin = count;
target = getAdc(0)*630L/4096L;
chThdSleep(chTimeMS2I(100));
}
}