Phatline Posted May 23, 2023 Report Posted May 23, 2023 (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 May 23, 2023 by Phatline
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now