Jump to content

use off AINSER slow down SD-Card Access

Recommended Posts


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


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:



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:

#define PRIORITY_TASK_SEQ	( tskIDLE_PRIORITY + 5 ) // higher priority than MIDI receive task!
#define PRIORITY_SD			( tskIDLE_PRIORITY + 3 )
#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)

	// 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
                                        FILE_WriteOpen    ("0.p4", 8);
                                        FILE_WriteBuffer(buffer2, sizeof(buffer2));

Edited by Phatline
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...