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](http://www.midibox.org/mios32/manual/group m_i_o_s32 s_p_i.html) 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()](http://www.midibox.org/mios32/manual/group m_i_o_s32 s_p_i.html#gabcdae72100df8b893ee4684ad6763afb) 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;