14.12.2012

Karta SD. Przygotowanie i kompilacja PK NET MF

Jak połączenia już mamy zrobione to teraz trzeba przygotować odpowiednio porting kit i skompilować. Aha. Kartę SD wcześniej formatujemy z życiem FAT32. Możemy też utworzyć na niej jakieś pliki. Najlepiej tekstowe. Kartę od razu wkładamy w holder. Przykład modyfikacji i kompilacji dla .NET Micro Framework PK 4.2 QFE2. W innej wersji PK powinno być podobnie.

Uruchamiamy SolutionWizard. Do czego służy i mniej więcej jak korzystać pokazałem wcześniej. Wybieramy modyfikację projektu Discovery4 i nic nie zmieniamy, aż do ekranu "Feature Selection". Tutaj zaznaczamy: "FileSystem" i "SD". A na następnym ekranie "Generate Template" dla tych dwóch nowych funkcjonalności. Dalej standardowo.

SolutionWizard- add FSSolutionWizard - add SD Card
 SolutionWizard - generate template

SolutionWizard zrobił dwie rzeczy w katalogu naszej solucji (C:\MicroFrameworkPK_v4_2\Solutions\Discovery4). Zmodyfikował plik TinyCLR\TinyCLR.proj oraz utworzył katalogi: DeviceCode\FileSystem_Config_PAL i DeviceCode\SD_Config_HAL. W pliku TinyCLR.proj dodał funkcjonalności: Stream, FileSystem i SD oraz odpowiednie drivery: Stream, SPOT_IO, fs_pal, SD_BL, FS_FAT, FileSystem_Config_PAL_Discovery4, SD_Config_HAL_Discovery4. Wywalił zaś zaślepki fs_pal_stubs i FS_Config_stubs. Nas tak naprawdę interesują dodane katalogi.

Katalog DeviceCode\SD_Config_HAL zawiera dwa pliki: proj i cpp. Plików proj nie ruszamy. Plik cpp zawiera konfigurację drivera SD. Czyli np. gdzie jest podłączona karta (który SPI), z jaka częstotliwością odbywa się komunikacja, który pin to CS (ChipSelect) itp. Wprowadzamy tam modyfikacje.

W linii 30 dodajemy:

#pragma arm section rwdata = "g_SD_DeviceRegisters"

Tak aby cały ten blok pragma wyglądał tak:

#if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
#pragma arm section rwdata = "g_SD_BS_Config"
#pragma arm section rwdata = "g_SD_DeviceRegisters"
#endif

W linii 81 (po definicji struct SD_BLOCK_CONFIG g_SD_BS_Config) dodajemy:

struct SD_DEVICE_REGISTERS g_SD_DeviceRegisters;

Tak aby cały blok definicji struct wyglądał tak:

struct SD_BLOCK_CONFIG g_SD_BS_Config =
{
    {
        SD_WP_GPIO_PIN,            // GPIO_PIN             Pin;
        SD_WP_ACTIVE,              // BOOL                 ActiveState;
    },

     &g_SD_DeviceInfo,             // BlockDeviceinfo
};

struct SD_DEVICE_REGISTERS g_SD_DeviceRegisters;

W linii 83 zaraz po definicjach struct zmieniamy pin z GPIO_PIN_NONE na PB12(dziesiętnie = 28), SD_MSK_SAMPLE_EDGE na TRUE (dane na zboczu narastającym zegara), częstotliwość zegara, oraz z którego interfejsu SPI ma korzystać (SPI1=0, SPI2=1, SPI3=2).

#define SD_CS                    (GPIO_PIN)28 // PB12
#define SD_MSK_SAMPLE_EDGE       TRUE // important
#define SD_CLOCK_RATE_KHZ        400 //check 10000
#define SD_MODULE                1 // SPI2

Tak aby cała konfiguracja wyglądała tak:

#define SD_CS                    (GPIO_PIN)28 // PB12
#define SD_CS_ACTIVE             FALSE
#define SD_MSK_IDLE              TRUE
#define SD_MSK_SAMPLE_EDGE       TRUE // important
#define SD_16BIT_OP              FALSE
#define SD_CLOCK_RATE_KHZ        400 //check 10000
#define SD_CS_SETUP_USEC         0
#define SD_CS_HOLD_USEC          0
#define SD_MODULE                1 // SPI2
#define SD_INSERT_ISR_PIN        GPIO_PIN_NONE
#define SD_EJECT_ISR_PIN         GPIO_PIN_NONE
#define SD_LOW_VOLTAGE_FLAG      FALSE

Częstotliwość zegara można zostawić na 400 kHz lub spróbować wyższą. U mnie karta chodzi bez problemów z częstotliwością 10000 kHz. Dodatkowo dla bezpieczeństwa można ustawić SD_CS_SETUP_USEC i SD_CS_HOLD_USEC na 1.

Katalog DeviceCode\FileSystem_Config_PAL również zawiera dwa pliki. I tak jak poprzednio modyfikujemy tylko cpp. Najpierw dodajemy obsługę FAT32.

W linii 10 po definicjach pragma dodajemy:

extern FILESYSTEM_DRIVER_INTERFACE g_FAT32_FILE_SYSTEM_DriverInterface;
extern STREAM_DRIVER_INTERFACE g_FAT32_STREAM_DriverInterface;

W linii 23 i 28 zmieniamy g_AvailableFSInterfaces i g_InstalledFSCount:

FILESYSTEM_INTERFACES g_AvailableFSInterfaces[] =
{
    { &g_FAT32_FILE_SYSTEM_DriverInterface, &g_FAT32_STREAM_DriverInterface },
};

const size_t g_InstalledFSCount = 1;


To nie wszystko. Trzeba jeszcze dodać kod odpowiedzialny za jej podmontowanie. Inaczej nie będziemy jej widzieli w .NET MF.

W linii 12 po dodanych liniach extern dodajemy:

extern struct BlockStorageDevice  g_SD_BS;
extern struct IBlockStorageDevice g_SD_BS_DeviceTable;
extern struct BLOCK_CONFIG        g_SD_BS_Config;

A w linii 23 ciało procedury FS_MountRemovableVolumes:

void FS_MountRemovableVolumes()
{
 if (BlockStorageList::AddDevice( &g_SD_BS, &g_SD_BS_DeviceTable, &g_SD_BS_Config, TRUE ));
 {
  FS_MountVolume( "SD", 0, 0, &g_SD_BS );  
 }
}

Uff. Cały plik FS_config_Discovery4.cpp ma wyglądać tak:

#include <tinyhal.h>

#if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
#pragma arm section rwdata = "g_AvailableFSInterfaces"
#endif

extern FILESYSTEM_DRIVER_INTERFACE g_FAT32_FILE_SYSTEM_DriverInterface;
extern STREAM_DRIVER_INTERFACE g_FAT32_STREAM_DriverInterface;

extern struct BlockStorageDevice  g_SD_BS;
extern struct IBlockStorageDevice g_SD_BS_DeviceTable;
extern struct BLOCK_CONFIG        g_SD_BS_Config;

void FS_AddVolumes()
{
}

void FS_MountRemovableVolumes()
{
 if (BlockStorageList::AddDevice( &g_SD_BS, &g_SD_BS_DeviceTable, &g_SD_BS_Config, TRUE ));
 {
  FS_MountVolume( "SD", 0, 0, &g_SD_BS );  
 }
}

FILESYSTEM_INTERFACES g_AvailableFSInterfaces[] =
{
    { &g_FAT32_FILE_SYSTEM_DriverInterface, &g_FAT32_STREAM_DriverInterface },
};
const size_t g_InstalledFSCount = 1;

#if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
#pragma arm section rwdata
#endif

Kompilujemy zgodnie z tym co napisałem wcześniej: Kompilacja Porting Kit dla STM32F4Discovery. Tutaj mała uwaga. Można śmiało poprawiać pliki i  kompilować bez usuwania katalogu C:\MicroFrameworkPK_v4_2\BuildOutput za każdym razem. Wówczas kompilacja przebiega znacznie szybciej. W wyniku kompilacji otrzymujemy pliki ER_CONFIG + ER_FLASH do wgrania tradycyjnie za pomocą MFDeploy.

Po zaprogramowaniu STM32F4Discovery kolejna próba. Uruchamiamy program napisany kilka postów wcześniej. Program normalnie się uruchomi, a VolumeInfo będzie jak na obrazku poniżej.


SD Card in NET MF on STM32F4Discovery

13.12.2012

Karta SD. Podłączenie sprzętu

Kartę SD będziemy podłączać do STM32F4Discovery przez interfejs SPI. Wyprowadzeń SD card nie będę rozpisywał, bo można sobie popatrzeć na wikipedi jak to wygląda. Przechodzimy do sedna. Użyjemy następujących wyprowadzeń karty:
  • 1 - CS (Card Select)
  • 2 - MOSI (Data IN)
  • 3 - GND (Ground)
  • 4 - VCC (Power)
  • 5 - SCL (Clock)
  • 6 - GND (Ground)
  • 7 - MISO(Data Out)
SD card + STM32F4DiscoveryPodłączanie karty na pająka czy lutowanie bezpośrednio do styków karty pozostawiam hardkorowcom. Ja użyłem holdera do karty SD kupionego za grosze. Przylutowałem do golpinów wyprowadzenia holdera i do testów powinno wystarczyć. Zastosowanie holdera ma jeszcze jedną zaletę. Przez specjalne ustawienie styków łączących, podczas wkładania i wyciągania karty, podłączanie i odłączanie zasilania i sygnałów danych odbywa się w odpowiedniej, bezpiecznej kolejności . 

Jak mowa o zasilaniu to miałem pewne obawy czy napięcie +3V (takie VDD ma płytka STM32F4 Discovery) wystarczy. Wszędzie piszą o zasilaniu z +3.3V. Popatrzyłem więc do dokumentacji SanDiska. Oni dopuszczają napięcie zasilające w zakresie: od +2.7V do +3.6V. Teraz z doświadczenia już wiem, że +3.0V w zupełności wystarczy. A używam karty Kongstona 128MB.

Ostatnie dwa piny holdera na razie nie są wykorzystywane. Przedostatni pin podłączony jest do styków sygnalizujących obecność karty, a ostatni do styków zabezpieczenia przed zapisem. W kartach SD to programista musi zadbać o rozpoznanie stanu blokady zapisu poprzez ten pin i odpowiednią jego obsługę.

Jak już wcześniej wspomniałem będziemy używać interfejsu SPI. Płytka STM32F4Discovery ma 3 interfejsy SPI. Piny drugiego z kolei portu: SPI2, są wolne więc użyjemy ich: PB13-SCL, PB14-MISO, PB15-MOSI, oraz PB12 jako CS. Schemat podłączenia poniżej:

SD card + NET MF + STM32F4Discovery


SD card + NET MF + STM32F4Discovery

12.12.2012

Karta SD w .NET MF na STM32F4Discovery

No oczywiście obsługi karty SD (SD card) nie mamy w porcie .NET Micro Framework dla STM32F4 Discovery. Sprawdzić to można prostym programem. Najpierw pobieramy obsługiwane systemy plików, a następnie odpytujemy o dostępne zasoby (wolumeny). Kot wygląda tak:

using Microsoft.SPOT;
using Microsoft.SPOT.IO;

public class Program
{
    public static void Main()
    {
        string[] availFs = VolumeInfo.GetFileSystems();
        if (availFs.Length == 0)
        {
            Debug.Print("No FS found");
            return;
        }

        foreach (string fs in availFs)
            Debug.Print("Available FS: " + fs);

        VolumeInfo[] volumes = VolumeInfo.GetVolumes();
        if(volumes.Length == 0)
        {
            Debug.Print("No volumes found");
            return;
        }

        foreach (VolumeInfo volume in volumes)
            Debug.Print("Volume: " + volume.Name);
    }
}

W wyniku dostaniemy wyjątek:

An unhandled exception of type 'System.NotSupportedException' occurred in Program.exe

Czyli na 100% nie mamy obsługi żadnego FAT, a co za tym idzie karty SD, w porcie NET MF dla STM32F4Discovery. Trzeba dodać FS i SD do solucji. 

Przez chwilę myślałem, że się nie da i miałem zrezygnować, ale teraz mogę powiedzieć, że karta SD działa w NET MF na STM32F4 Discovery poprawnie. I dodanie jej wcale nie jest trudne. Największym problemem dla takiego lamera jak ja było rozgryzienie co i jak trzeba poupychać w solucji.


8.12.2012

Brak komunikacji z VS (zdechły kot)

Czasami może się zdarzyć, że coś sknocimy w naszym programie i Visual Studio nie będzie się mógł połączyć z płytką STM32F4 Discovery. Mnie się to zdarzyło kilka razy podczas zabaw z portem USB. 

Co wówczas robimy? Wciskamy na płytce przycisk user button (to ten niebieski), przytrzymujemy go i naciskamy przycisk resetu (to ten czarny). Puszczamy oba przyciski. Powinny zapalić się trzy diody na płytce (bez niebieskiej). Oznacza to, że uruchomił się jedynie tinybooter, a nie nasz program. Teraz odpalamy MFDeploy i przyciskiem Erase usuwamy deployment. Proste?

7.12.2012

Nowa wersja .NET MF

Kilka dni temu pojawił się .NET MF 4.3 (RTM). Zawiera wszystkie funkcjonalności i poprawki z wersji .NET MF 4.2 QFE.

Najważniejsze zmiany to:
  • przystosowanie do Visual Studio 2012
  • zmniejszenie czasu uruchamiania
  • skrót do MFDeploy w menu start
  • poprawka funkcji ToString("d4")
  • wynik funkcji ToBase64String zgodny z wersją .NET na PC
  • poprawki driverów sieci i usb
  • dodanie do ExtendedWeakReferences funkcji Flush
Przystosowanie do Visual Studio 2012 w praktyce oznacza, że wersja 4.3 nie będzie już dostępna dla Visual Studio 2010.