Jump to content

Recommended Posts

Posted (edited)

Hei

I have some SPI problems here... A AINSER slows down the SD-Card Access - so the programm is not usable anymore.

I already optimized the Ainser-Side (see below), but that is not enough, I dont know if it is the prescaler Factor, that also changes SD-Card in a way (since booth are SPI...)

I save a lot off informations on the SD-Card, so each percent off performance makes seconds off less waiting time.

 Is there something like a prescaler that can be set for the SD-Card?=

How give the SD-Card more priority? I know how to give prioritys for RTOS Task that i created, but i dont know how to do that with SD-Card (on rootlevel)

 

thx for any info!

 

 

I have 2 AINSER8 moduels connected to a STM32F4(disconver), not multiplexed - i have 16 faders connected directly to them.
as soon i scan the AINSER:

static void TASK_AINSER_Scan(void *pvParameters){	// This task scans AINSER pins and checks for updates

  portTickType xLastExecutionTime;
  xLastExecutionTime = xTaskGetTickCount();

  while( 1 ) {
    vTaskDelayUntil(&xLastExecutionTime, 10 / portTICK_RATE_MS);	// 202 orginally 1ms
	
			// scan pins
			AINSER_Handler(APP_AINSER_NotifyChange);
			}
}

 

The Write or Read on the SD-Card goes up from 1seconds to 14seconds (in my case)

so i copied the ainser.c to my project, and made some edits, the most significant emprovement was to change the prescaler from 64 to 8:

// init SPI port for fast frequency access
MIOS32_SPI_TransferModeInit(2, MIOS32_SPI_MODE_CLK0_PHASE0, MIOS32_SPI_PRESCALER_8); // Initialisierung des SPI-Ports

i also tryd other values, but on some values the Ainser didnt react at all, or i got random values.

When i remove this Prescaler LINE, the AINSER gives no output to my code, what makes me a bit wondering since in MIOS-FUNCTIONS there is statet:

 

Quote

J19 provides two RCLK (alias Chip Select) lines.
It's a software emulated SPI, therefore the selected spi_prescaler has no effect! Bytes are transfered so fast as possible. The usage of MIOS32_SPI_PIN_DRIVER_STRONG is strongly recommented ;)
DMA transfers are not supported by the emulation, so that MIOS32_SPI_TransferBlock() will consume CPU time (but the callback handling does work).

So my expirience - the Prescale may not have a effect on SPI2, but on SPI0 (where my SD-Card is connected).

 

I also changed to get this Prescaler8 working, The driver from MIOS32_SPI_PIN_DRIVER_STRONG    to     MIOS32_SPI_PIN_DRIVER_WEAK (which is i know not recommented):

// pins in push-poll mode (3.3V output voltage)
MIOS32_SPI_IO_Init(2, MIOS32_SPI_PIN_DRIVER_WEAK);	// 2: Ainser_SPI - J19


i then tryed to remove the Multiplexer Code, and fixed the modules to a count off 2,
At the end i have 4 seconds Access Time to my SD Card

which was without AINSerial 1second

And without my modifications 14 seconds

 

I already set the priority off Tasks like this:

// TASK   - PRIORITYS
#define PRIORITY_TASK_SEQ	( tskIDLE_PRIORITY + 5 ) // higher priority than MIDI receive task!
#define PRIORITY_SD			( tskIDLE_PRIORITY + 3 )
#define PRIORITY_LOPRIO		( tskIDLE_PRIORITY + 2 )
#define PRIORITY_LCD		( tskIDLE_PRIORITY + 0 ) // idle
#define PRIORITY_PAD		( tskIDLE_PRIORITY + 0 ) // idle
#define PRIORITY_TASK_AINSER_SCAN ( tskIDLE_PRIORITY + 0 )	// orginal this was 3

So the SD-Task (where i write things on the SD-Card with mutexes and stuff...) is already High priority > off course the SEQuencer is higher...

 


the whole Ainser.c code then looked like this:

#include <mios32.h>
#include "ainser.h"
#include <string.h>



/////////////////////////////////////////////////////////////////////////////
// Local variables
/////////////////////////////////////////////////////////////////////////////

static u8 ainser_enable_mask;
static u8 ainser_muxed_mask;

static u16 ain_pin_values[16];	//2 Modules  8 pins
static u16 previous_ain_pin_value;

const u8 pin_lookup[8] = {7,6,5,4,3,2,1,0};



/////////////////////////////////////////////////////////////////////////////
// Local Prototypes
/////////////////////////////////////////////////////////////////////////////

static s32 AINSER_SetCs(u8 module, u8 value);


/////////////////////////////////////////////////////////////////////////////
//! Initializes AINSER driver
//! Should be called from Init() during startup
/////////////////////////////////////////////////////////////////////////////
s32 AINSER_Init(u32 mode){

	// pins in push-poll mode (3.3V output voltage)
	MIOS32_SPI_IO_Init(2, MIOS32_SPI_PIN_DRIVER_WEAK);	// 2: Ainser_SPI - J19		// orginal this was MIOS32_SPI_PIN_DRIVER_STRONG   MIOS32_SPI_PIN_DRIVER_WEAK


	// ensure that CS is deactivated
	AINSER_SetCs(0, 1);	// CS für Module 0
	AINSER_SetCs(1, 1);	// CS für Module 1

	// Dont use Muxes
	ainser_muxed_mask &= ~3;

	// Sets the enable mask for modules which should be scanned
	ainser_enable_mask |= 3;

	// clear all values
	memset(ain_pin_values, 0, sizeof(ain_pin_values));

	previous_ain_pin_value = 0;

  return 0;
}



/////////////////////////////////////////////////////////////////////////////
//! This function should be periodically called to scan AIN pin changes.
//! A scan of a single multiplexer selection takes ca. 50 uS on a LPC1769 with MIOS32_SPI_PRESCALER_8
/////////////////////////////////////////////////////////////////////////////

s32 AINSER_Handler(void (*_callback)(u32 module, u32 pin, u32 value)) {

    static u8 first_scan_done = 0; // Variable zur Verfolgung des ersten Scans

    // init SPI port for fast frequency access
    MIOS32_SPI_TransferModeInit(2, MIOS32_SPI_MODE_CLK0_PHASE0, MIOS32_SPI_PRESCALER_8); // Initialisierung des SPI-Ports

    // loop over connected modules
    int module;
    int chn;
    for (module=0; module<2; ++module){ // Schleife über die angeschlossenen Module

	       for (chn = 0; chn < 8; ++chn) { // Schleife über die Kanäle
								            AINSER_SetCs(module, 0); 						// Setzen des Chip-Select-Pins auf LOW



								            MIOS32_SPI_TransferByte(2, 0x06 | (chn >> 2));
								            u8 b1 = MIOS32_SPI_TransferByte(2, chn << 6);	// Übertragung der Datenbytes über SPI
								            u8 b2 = MIOS32_SPI_TransferByte(2, 0);


								            AINSER_SetCs(module, 1); 						// Setzen des Chip-Select-Pins auf HIGH


								            u8 pin = pin_lookup[chn]; 								// Berechnung des Pin-Index
								            u16 value = (b2 | (b1 << 8)) & 0xFFF; 			// Kombination der Datenbytes zu einem Wert
								            previous_ain_pin_value = ain_pin_values[module * 8 + pin]; // Speichern des vorherigen Pin-Werts

								            int diff = value - previous_ain_pin_value; 		// Berechnung der Differenz zum vorherigen Wert
								            int abs_diff = (diff > 0) ? diff : -diff; 		// Berechnung des absoluten Werts der Differenz

								            // Überprüfung, ob der Pin-Wert sich ausreichend geändert hat
								            if (!first_scan_done || abs_diff > 31) {
																	                ain_pin_values[module * 8 + pin] = value; // Speichern des neuen Pin-Werts
																	                if (first_scan_done && _callback && pin < 8)
																	                    _callback(module, pin, value); // Aufruf der Callback-Funktion
																					}
								        }
								    }

    if (first_scan_done == 0)
        first_scan_done = 1; // Setzen der Flag, dass der erste Scan abgeschlossen ist

    return 0;
}




/////////////////////////////////////////////////////////////////////////////
// Internal function to set CS line depending on module
/////////////////////////////////////////////////////////////////////////////
static s32 AINSER_SetCs(u8 module, u8 value){

  switch( module ){
				  case 0: return MIOS32_SPI_RC_PinSet(2, 0, value); // spi, rc_pin, pin_value			// 2: SPI - J19
				  case 1: return MIOS32_SPI_RC_PinSet(2, 1, value); // spi, rc_pin, pin_value			// 2: SPI - J19
				  }
  return -1;
}


 

i use to write to SD-card directly with File.c, like this:

                                    // Speicherung der Daten auf der SD-Karte
 
                                    MUTEX_SDCARD_TAKE;
                                        FILE_WriteOpen    ("0.p4", 8);
                                        FILE_WriteBuffer(buffer2, sizeof(buffer2));
                                        FILE_WriteClose();
                                    MUTEX_SDCARD_GIVE;

Edited by Phatline

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...