summaryrefslogtreecommitdiff
path: root/openpicc/application/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'openpicc/application/main.c')
-rw-r--r--openpicc/application/main.c153
1 files changed, 89 insertions, 64 deletions
diff --git a/openpicc/application/main.c b/openpicc/application/main.c
index e1749de..d9b35f1 100644
--- a/openpicc/application/main.c
+++ b/openpicc/application/main.c
@@ -30,6 +30,7 @@
#include <FreeRTOS.h>
#include <AT91SAM7.h>
+#include <lib_AT91SAM7.h>
#include <USB-CDC.h>
#include <task.h>
@@ -50,14 +51,89 @@
#include "iso14443_sniffer.h"
#include "decoder.h"
+static inline int detect_board(void)
+{
+ /* OpenPICC board detection logic.
+ * Interesting board differences: PA31 is open on OPENPICC_v0_4 and connected
+ * to PA18 on OPENPICC_v0_4_p1. PA18 is connected to U7 on both and might read
+ * differently depending on the state of U7 (primarily depending on U5 and the
+ * receive circuitry).
+ * Strategy: Enable Pullups, read PA31 and PA18, if both read low then U7 is
+ * switched through and this is an v0.4p1. If PA18 reads low and PA31 reads high
+ * then U7 is switched through and this is an v0.4. If both read high, then U7 is
+ * not switched through and it might be either board. In this case drive PA31 down
+ * and see whether PA18 follows down, then it's a v0.4p1 otherwise a v0.4.
+ */
+ int result = -1;
+
+ AT91PS_PIO pio = AT91C_BASE_PIOA;
+ u_int32_t old_OSR = pio->PIO_OSR,
+ old_ODSR = pio->PIO_ODSR,
+ old_PUSR = pio->PIO_PPUSR,
+ old_PSR = pio->PIO_PSR;
+
+ pio->PIO_ODR = AT91C_PIO_PA18 | AT91C_PIO_PA31;
+ pio->PIO_PER = AT91C_PIO_PA18 | AT91C_PIO_PA31;
+ pio->PIO_PPUER = AT91C_PIO_PA18 | AT91C_PIO_PA31;
+
+ unsigned int pa18 = AT91F_PIO_IsInputSet(pio, AT91C_PIO_PA18),
+ pa31 = AT91F_PIO_IsInputSet(pio, AT91C_PIO_PA31);
+ if(!pa18 && !pa31) {
+ //vLedInit();
+ //vLedHaltBlinking(1);
+ result = OPENPICC_v0_4_p2;
+ } else if(!pa18 && pa31) {
+ vLedInit();
+ vLedHaltBlinking(2);
+ // Needs to be tested, should be v0.4
+ } else if(pa18 && pa31) {
+ // Can be either board
+ pio->PIO_OER = AT91C_PIO_PA31;
+ pio->PIO_CODR = AT91C_PIO_PA31;
+ pa18 = AT91F_PIO_IsInputSet(pio, AT91C_PIO_PA18);
+ if(!pa18) {
+ result = OPENPICC_v0_4_p2;
+ } else {
+ vLedInit();
+ vLedHaltBlinking(3);
+ // Needs to be tested, should be v0.4
+ }
+
+ // Restore state
+ if( old_OSR & AT91C_PIO_PA31 ) {
+ pio->PIO_OER = AT91C_PIO_PA31;
+ if(old_ODSR & AT91C_PIO_PA31) {
+ pio->PIO_SODR = AT91C_PIO_PA31;
+ } else {
+ pio->PIO_CODR = AT91C_PIO_PA31;
+ }
+ } else {
+ pio->PIO_ODR = AT91C_PIO_PA31;
+ }
+ }
+
+ // Restore state
+ if(old_PSR & AT91C_PIO_PA18) pio->PIO_PER = AT91C_PIO_PA18; else pio->PIO_PDR = AT91C_PIO_PA18;
+ if(old_PSR & AT91C_PIO_PA31) pio->PIO_PER = AT91C_PIO_PA31; else pio->PIO_PDR = AT91C_PIO_PA31;
+
+ if(old_PUSR & AT91C_PIO_PA18) pio->PIO_PPUDR = AT91C_PIO_PA18; else pio->PIO_PPUER = AT91C_PIO_PA18;
+ if(old_PUSR & AT91C_PIO_PA31) pio->PIO_PPUDR = AT91C_PIO_PA31; else pio->PIO_PPUER = AT91C_PIO_PA31;
+
+ return result;
+}
+
/**********************************************************************/
static inline void prvSetupHardware (void)
{
/* The very, very first thing we do is setup the global OPENPICC variable to point to
* the correct hardware information.
- * FIXME: Detect dynamically in the future
*/
- OPENPICC = &OPENPICC_HARDWARE[OPENPICC_v0_4_p1];
+ int release = detect_board();
+ if(release < 0) {
+ vLedInit();
+ vLedHaltBlinking(0);
+ }
+ OPENPICC = &OPENPICC_HARDWARE[release];
/* When using the JTAG debugger the hardware is not always initialised to
@@ -89,68 +165,8 @@ void vApplicationIdleHook(void)
//vLedSetGreen(0);
disabled_green = 1;
}
- usb_print_flush();
}
-#if 0
-// Bitrotten
-void main_help_print_buffer(ssc_dma_rx_buffer_t *buffer, int *pktcount)
-{
- ISO14443A_SHORT_TYPE *tmp = (ISO14443A_SHORT_TYPE*)buffer->data;
- int i, dumped = 0;
- unsigned int j;
- for(i = buffer->len / (sizeof(*tmp)*8); i >= 0 ; i--) {
- if( *tmp != 0x00000000 ) {
- if(dumped == 0) {
- DumpUIntToUSB(buffer->len);
- DumpStringToUSB(", ");
- DumpUIntToUSB((*pktcount)++);
- DumpStringToUSB(": ");
- } else {
- DumpStringToUSB(" ");
- }
- dumped = 1;
- DumpUIntToUSB(buffer->len / (sizeof(*tmp)*8) - i);
- DumpStringToUSB(": ");
- for(j=0; j<sizeof(*tmp)*8; j++) {
- usb_print_char_f( (((*tmp) >> j) & 0x1) ? '1' : '_' , 0);
- }
- usb_print_flush();
- //DumpBufferToUSB((char*)(tmp), sizeof(*tmp));
- }
- tmp++;
- }
- if(dumped) DumpStringToUSB("\n\r");
-}
-
-void vMainTestSSCRXConsumer (void *pvParameters)
-{
- static int pktcount=0;
- (void)pvParameters;
- while(1) {
- ssc_dma_rx_buffer_t* buffer;
- if(xQueueReceive(ssc_rx_queue, &buffer, portMAX_DELAY)) {
- portENTER_CRITICAL();
- buffer->state = PROCESSING;
- portEXIT_CRITICAL();
- /*vLedBlinkGreen();
- for(i=0; i<buffer->len*8; i++) {
- vLedSetGreen( buffer->data[i/8] & (1<<(i%8)) );
- }
- vLedBlinkGreen();*/
- //i = usb_print_set_default_flush(0);
-
- main_help_print_buffer(buffer, &pktcount);
-
- //usb_print_set_default_flush(i);
- portENTER_CRITICAL();
- buffer->state = FREE;
- portEXIT_CRITICAL();
- }
- }
-}
-#endif
-
/* This task pings the watchdog even when the idle task is not running
* It should be started with a very high priority and will delay most of the time */
void vMainWatchdogPinger (void *pvParameters)
@@ -164,6 +180,15 @@ void vMainWatchdogPinger (void *pvParameters)
}
}
+void usb_print_flusher (void *pvParameters)
+{
+ (void)pvParameters;
+ while(1) {
+ usb_print_flush();
+ vTaskDelay(100*portTICK_RATE_MS);
+ }
+}
+
/**********************************************************************/
int main (void)
{
@@ -178,8 +203,8 @@ int main (void)
da_init();
adc_init();
- /*xTaskCreate (vMainTestSSCRXConsumer, (signed portCHAR *) "SSC_CONSUMER", TASK_USB_STACK,
- NULL, TASK_USB_PRIORITY, NULL);*/
+ xTaskCreate (usb_print_flusher, (signed portCHAR *) "PRINT-FLUSH", TASK_USB_STACK,
+ NULL, TASK_USB_PRIORITY, NULL);
/*xTaskCreate (iso14443_layer3a_state_machine, (signed portCHAR *) "ISO14443A-3", TASK_ISO_STACK,
NULL, TASK_ISO_PRIORITY, NULL);*/
xTaskCreate (iso14443_sniffer, (signed portCHAR *) "ISO14443-SNIFF", TASK_ISO_STACK,
personal git repositories of Harald Welte. Your mileage may vary