kopia lustrzana https://github.com/OpenRTX/OpenRTX
MD9600: updated nvm driver
rodzic
23e4ce0a8a
commit
9dc449396a
|
@ -209,7 +209,6 @@ stm32f405_src = ['platform/mcu/STM32F4xx/boot/startup.cpp',
|
|||
'platform/mcu/STM32F4xx/drivers/usb_vcom.c',
|
||||
'platform/mcu/STM32F4xx/drivers/delays.cpp',
|
||||
'platform/mcu/STM32F4xx/drivers/rtc.c',
|
||||
'platform/mcu/STM32F4xx/drivers/SPI2.c',
|
||||
'platform/mcu/STM32F4xx/drivers/USART3.cpp',
|
||||
'platform/mcu/STM32F4xx/drivers/flash.c',
|
||||
'platform/mcu/STM32F4xx/drivers/rng.c',
|
||||
|
@ -372,11 +371,11 @@ mduv3x0_def += openrtx_def + stm32f405_def + miosix_cm4f_def
|
|||
## TYT MD-9600
|
||||
##
|
||||
md9600_src = ['platform/targets/MD-9600/platform.c',
|
||||
'platform/targets/MD-9600/hwconfig.c',
|
||||
'platform/drivers/display/ST7567_MD9600.c',
|
||||
'platform/drivers/keyboard/keyboard_MD9600.c',
|
||||
'platform/drivers/chSelector/chSelector_MD9600.c',
|
||||
'platform/drivers/baseband/radio_MD9600.cpp',
|
||||
'platform/drivers/NVM/spiFlash_MD9600.c',
|
||||
'platform/drivers/CPS/cps_io_native_MD9600.c']
|
||||
|
||||
md9600_inc = ['platform/targets/MD-9600']
|
||||
|
|
|
@ -22,11 +22,13 @@
|
|||
#include <string.h>
|
||||
#include <interfaces/nvmem.h>
|
||||
#include <interfaces/delays.h>
|
||||
#include <calibInfo_MDx.h>
|
||||
#include <nvmem_access.h>
|
||||
#include <utils.h>
|
||||
#include "cps_data_MDUV3x0.h"
|
||||
#include "W25Qx.h"
|
||||
|
||||
extern const struct nvmDevice eflash;
|
||||
|
||||
//static const uint32_t vfoChannelBaseAddr = 0x2EF00; /**< Base address of VFO channel */
|
||||
static const uint32_t zoneBaseAddr = 0x149E0; /**< Base address of zones */
|
||||
static const uint32_t zoneExtBaseAddr = 0x31000; /**< Base address of zone extensions */
|
||||
|
@ -36,17 +38,18 @@ static const uint32_t maxNumChannels = 3000; /**< Maximum number of cha
|
|||
static const uint32_t maxNumZones = 250; /**< Maximum number of zones and zone extensions in memory */
|
||||
static const uint32_t maxNumContacts = 10000; /**< Maximum number of contacts in memory */
|
||||
|
||||
static inline void W25Qx_readData(uint32_t addr, void *buf, size_t len)
|
||||
{
|
||||
nvm_devRead(&eflash, addr, buf, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to read channel data from SPI flash into a channel_t struct
|
||||
*/
|
||||
static int _readChannelAtAddress(channel_t *channel, uint32_t addr)
|
||||
{
|
||||
W25Qx_wakeup();
|
||||
delayUs(5);
|
||||
mduv3x0Channel_t chData;
|
||||
W25Qx_readData(addr, ((uint8_t *) &chData), sizeof(mduv3x0Channel_t));
|
||||
W25Qx_sleep();
|
||||
|
||||
// Check if the channel is empty
|
||||
#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
|
||||
|
@ -171,16 +174,12 @@ int cps_readBankHeader(bankHdr_t *b_header, uint16_t pos)
|
|||
{
|
||||
if(pos >= maxNumZones) return -1;
|
||||
|
||||
W25Qx_wakeup();
|
||||
delayUs(5);
|
||||
|
||||
mduv3x0Zone_t zoneData;
|
||||
mduv3x0ZoneExt_t zoneExtData;
|
||||
uint32_t zoneAddr = zoneBaseAddr + pos * sizeof(mduv3x0Zone_t);
|
||||
uint32_t zoneExtAddr = zoneExtBaseAddr + pos * sizeof(mduv3x0ZoneExt_t);
|
||||
W25Qx_readData(zoneAddr, ((uint8_t *) &zoneData), sizeof(mduv3x0Zone_t));
|
||||
W25Qx_readData(zoneExtAddr, ((uint8_t *) &zoneExtData), sizeof(mduv3x0ZoneExt_t));
|
||||
W25Qx_sleep();
|
||||
|
||||
// Check if zone is empty
|
||||
#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
|
||||
|
@ -200,16 +199,12 @@ int cps_readBankData(uint16_t bank_pos, uint16_t ch_pos)
|
|||
{
|
||||
if(bank_pos >= maxNumZones) return -1;
|
||||
|
||||
W25Qx_wakeup();
|
||||
delayUs(5);
|
||||
|
||||
mduv3x0Zone_t zoneData;
|
||||
mduv3x0ZoneExt_t zoneExtData;
|
||||
uint32_t zoneAddr = zoneBaseAddr + bank_pos * sizeof(mduv3x0Zone_t);
|
||||
uint32_t zoneExtAddr = zoneExtBaseAddr + bank_pos * sizeof(mduv3x0ZoneExt_t);
|
||||
W25Qx_readData(zoneAddr, ((uint8_t *) &zoneData), sizeof(mduv3x0Zone_t));
|
||||
W25Qx_readData(zoneExtAddr, ((uint8_t *) &zoneExtData), sizeof(mduv3x0ZoneExt_t));
|
||||
W25Qx_sleep();
|
||||
|
||||
// Check if zone is empty
|
||||
#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
|
||||
|
@ -226,13 +221,9 @@ int cps_readContact(contact_t *contact, uint16_t pos)
|
|||
{
|
||||
if(pos >= maxNumContacts) return -1;
|
||||
|
||||
W25Qx_wakeup();
|
||||
delayUs(5);
|
||||
|
||||
mduv3x0Contact_t contactData;
|
||||
uint32_t contactAddr = contactBaseAddr + pos * sizeof(mduv3x0Contact_t);
|
||||
W25Qx_readData(contactAddr, ((uint8_t *) &contactData), sizeof(mduv3x0Contact_t));
|
||||
W25Qx_sleep();
|
||||
|
||||
// Check if contact is empty
|
||||
if(wcslen((wchar_t *) contactData.name) == 0) return -1;
|
||||
|
|
|
@ -33,7 +33,11 @@
|
|||
|
||||
static const struct W25QxCfg eflashCfg =
|
||||
{
|
||||
#ifdef PLATFORM_MD9600
|
||||
.spi = &spi2,
|
||||
#else
|
||||
.spi = &nvm_spi,
|
||||
#endif
|
||||
.cs = { FLASH_CS }
|
||||
};
|
||||
|
||||
|
@ -67,11 +71,14 @@ static const struct nvmDescriptor nvmDevices[] =
|
|||
|
||||
void nvm_init()
|
||||
{
|
||||
#ifndef PLATFORM_MD9600
|
||||
gpio_setMode(FLASH_CLK, ALTERNATE | ALTERNATE_FUNC(5));
|
||||
gpio_setMode(FLASH_SDO, ALTERNATE | ALTERNATE_FUNC(5));
|
||||
gpio_setMode(FLASH_SDI, ALTERNATE | ALTERNATE_FUNC(5));
|
||||
|
||||
spiStm32_init(&nvm_spi, 21000000, 0);
|
||||
#endif
|
||||
|
||||
W25Qx_init(&eflash);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <peripherals/gpio.h>
|
||||
#include <peripherals/spi.h>
|
||||
#include <interfaces/display.h>
|
||||
#include <interfaces/delays.h>
|
||||
#include "hwconfig.h"
|
||||
#include <SPI2.h>
|
||||
|
||||
|
||||
/**
|
||||
|
@ -57,10 +57,7 @@ static void display_renderRow(uint8_t row, uint8_t *frameBuffer)
|
|||
}
|
||||
}
|
||||
|
||||
for (uint8_t s = 0; s < 8; s++)
|
||||
{
|
||||
(void) spi2_sendRecv(tmp[s]);
|
||||
}
|
||||
spi_send(&spi2, tmp, 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,21 +76,24 @@ void display_init()
|
|||
gpio_setPin(LCD_RST);
|
||||
delayMs(5);
|
||||
|
||||
uint8_t initData[] =
|
||||
{
|
||||
0x2F, /* Voltage Follower On */
|
||||
0x81, /* Set Electronic Volume */
|
||||
0x15, /* Contrast, initial setting */
|
||||
0xA2, /* Set Bias = 1/9 */
|
||||
0xA1, /* A0 Set SEG Direction */
|
||||
0xC0, /* Set COM Direction */
|
||||
0xA4, /* White background, black pixels */
|
||||
0xAF, /* Set Display Enable */
|
||||
};
|
||||
|
||||
spi2_lockDeviceBlocking();
|
||||
spi_acquire(&spi2);
|
||||
gpio_clearPin(LCD_CS);
|
||||
|
||||
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
||||
(void) spi2_sendRecv(0x2F); /* Voltage Follower On */
|
||||
(void) spi2_sendRecv(0x81); /* Set Electronic Volume */
|
||||
(void) spi2_sendRecv(0x15); /* Contrast, initial setting */
|
||||
(void) spi2_sendRecv(0xA2); /* Set Bias = 1/9 */
|
||||
(void) spi2_sendRecv(0xA1); /* A0 Set SEG Direction */
|
||||
(void) spi2_sendRecv(0xC0); /* Set COM Direction */
|
||||
(void) spi2_sendRecv(0xA4); /* White background, black pixels */
|
||||
(void) spi2_sendRecv(0xAF); /* Set Display Enable */
|
||||
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
||||
spi_send(&spi2, initData, sizeof(initData));
|
||||
gpio_clearPin(LCD_CS);
|
||||
spi2_releaseDevice();
|
||||
spi_release(&spi2);
|
||||
}
|
||||
|
||||
void display_terminate()
|
||||
|
@ -103,21 +103,24 @@ void display_terminate()
|
|||
|
||||
void display_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
||||
{
|
||||
spi2_lockDeviceBlocking();
|
||||
spi_acquire(&spi2);
|
||||
gpio_clearPin(LCD_CS);
|
||||
|
||||
for(uint8_t row = startRow; row < endRow; row++)
|
||||
{
|
||||
uint8_t command[3];
|
||||
command[0] = 0xB0 | row; /* Set Y position */
|
||||
command[1] = 0x10; /* Set X position */
|
||||
command[2] = 0x04;
|
||||
|
||||
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
||||
(void) spi2_sendRecv(0xB0 | row); /* Set Y position */
|
||||
(void) spi2_sendRecv(0x10); /* Set X position */
|
||||
(void) spi2_sendRecv(0x04);
|
||||
spi_send(&spi2, command, 3);
|
||||
gpio_setPin(LCD_RS); /* RS high -> data mode */
|
||||
display_renderRow(row, (uint8_t *) fb);
|
||||
}
|
||||
|
||||
gpio_setPin(LCD_CS);
|
||||
spi2_releaseDevice();
|
||||
spi_release(&spi2);
|
||||
}
|
||||
|
||||
void display_render(void *fb)
|
||||
|
@ -127,15 +130,17 @@ void display_render(void *fb)
|
|||
|
||||
void display_setContrast(uint8_t contrast)
|
||||
{
|
||||
spi2_lockDeviceBlocking();
|
||||
uint8_t command[2];
|
||||
command[0] = 0x81; /* Set Electronic Volume */
|
||||
command[1] = contrast >> 2; /* Controller contrast range is 0 - 63 */
|
||||
|
||||
spi_acquire(&spi2);
|
||||
gpio_clearPin(LCD_CS);
|
||||
|
||||
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
||||
(void) spi2_sendRecv(0x81); /* Set Electronic Volume */
|
||||
(void) spi2_sendRecv(contrast >> 2); /* Controller contrast range is 0 - 63 */
|
||||
|
||||
gpio_clearPin(LCD_RS); /* RS low -> command mode */
|
||||
spi_send(&spi2, command, 2);
|
||||
gpio_setPin(LCD_CS);
|
||||
spi2_releaseDevice();
|
||||
spi_release(&spi2);
|
||||
}
|
||||
|
||||
void display_setBacklightLevel(uint8_t level)
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2021 - 2023 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include "SPI2.h"
|
||||
#include <pthread.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
void spi2_init()
|
||||
{
|
||||
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
|
||||
__DSB();
|
||||
|
||||
SPI2->CR1 = SPI_CR1_SSM /* Software managment of nCS */
|
||||
| SPI_CR1_SSI /* Force internal nCS */
|
||||
| SPI_CR1_BR_2 /* Fclock: 42MHz/32 = 1.3MHz */
|
||||
| SPI_CR1_MSTR /* Master mode */
|
||||
| SPI_CR1_SPE; /* Enable peripheral */
|
||||
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
}
|
||||
|
||||
void spi2_terminate()
|
||||
{
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN;
|
||||
__DSB();
|
||||
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
uint8_t spi2_sendRecv(const uint8_t val)
|
||||
{
|
||||
SPI2->DR = val;
|
||||
while((SPI2->SR & SPI_SR_RXNE) == 0) ;
|
||||
return SPI2->DR;
|
||||
}
|
||||
|
||||
bool spi2_lockDevice()
|
||||
{
|
||||
if(pthread_mutex_trylock(&mutex) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void spi2_lockDeviceBlocking()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
|
||||
void spi2_releaseDevice()
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2021 - 2023 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SPI2_H
|
||||
#define SPI2_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* Initialise SPI2 peripheral with a bus clock frequency of ~1.3MHz.
|
||||
* NOTE: this driver does not configure the SPI GPIOs, which have to be put in
|
||||
* alternate mode by application code.
|
||||
*/
|
||||
void spi2_init();
|
||||
|
||||
/**
|
||||
* Shut down SPI2 peripheral.
|
||||
* NOTE: is left to application code to change the operating mode of the SPI
|
||||
* GPIOs
|
||||
*/
|
||||
void spi2_terminate();
|
||||
|
||||
/**
|
||||
* Exchange one byte over the SPI bus.
|
||||
* @param val: transmitted byte.
|
||||
* @return incoming byte from slave device.
|
||||
*/
|
||||
uint8_t spi2_sendRecv(const uint8_t val);
|
||||
|
||||
/**
|
||||
* Acquire exclusive ownership on the SPI peripheral by locking an internal
|
||||
* mutex. This function is nonblocking and returs true if mutex has been
|
||||
* successfully locked by the caller.
|
||||
* @return true if device has been locked.
|
||||
*/
|
||||
bool spi2_lockDevice();
|
||||
|
||||
/**
|
||||
* Acquire exclusive ownership on the SPI peripheral by locking an internal
|
||||
* mutex. In case mutex is already locked, this function blocks the execution
|
||||
* flow until it becomes free again.
|
||||
*/
|
||||
void spi2_lockDeviceBlocking();
|
||||
|
||||
/**
|
||||
* Release exclusive ownership on the SPI peripheral.
|
||||
*/
|
||||
void spi2_releaseDevice();
|
||||
|
||||
#endif /* SPI2_H */
|
|
@ -1,8 +1,8 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2020 - 2023 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* Copyright (C) 2024 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN, *
|
||||
* Frederik Saraci IU2NRO, *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
|
@ -18,28 +18,10 @@
|
|||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include <peripherals/gpio.h>
|
||||
#include <hwconfig.h>
|
||||
#include <stdint.h>
|
||||
#include <SPI2.h>
|
||||
#include <spi_stm32.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/*
|
||||
* Implementation of external flash SPI interface for MD9600 devices.
|
||||
*/
|
||||
static pthread_mutex_t spi2Mutex;
|
||||
|
||||
uint8_t spiFlash_SendRecv(uint8_t val)
|
||||
{
|
||||
spi2_lockDeviceBlocking();
|
||||
uint8_t x = spi2_sendRecv(val);
|
||||
spi2_releaseDevice();
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void spiFlash_init()
|
||||
{
|
||||
}
|
||||
|
||||
void spiFlash_terminate()
|
||||
{
|
||||
}
|
||||
SPI_STM32_DEVICE_DEFINE(spi2, SPI2, &spi2Mutex)
|
|
@ -28,6 +28,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const struct spiDevice spi2;
|
||||
|
||||
/* Device has a working real time clock */
|
||||
#define CONFIG_RTC
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ extern "C" {
|
|||
#define BEEP_OUT GPIOC,8 /* CTCSS tone */
|
||||
|
||||
/* SPI2, connected to external flash and LCD */
|
||||
#define FLASH_CS GPIOB,12
|
||||
#define FLASH_CS &GpioB,12
|
||||
#define SPI2_CLK GPIOB,13
|
||||
#define SPI2_SDO GPIOB,14
|
||||
#define SPI2_SDI GPIOB,15
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <toneGenerator_MDx.h>
|
||||
#include <peripherals/rtc.h>
|
||||
#include <interfaces/audio.h>
|
||||
#include <SPI2.h>
|
||||
#include <spi_stm32.h>
|
||||
#include <chSelector.h>
|
||||
|
||||
/* TODO: Hardcoded hwInfo until we implement reading from flash */
|
||||
|
@ -66,8 +66,7 @@ void platform_init()
|
|||
gpio_setMode(SPI2_CLK, ALTERNATE | ALTERNATE_FUNC(5));
|
||||
gpio_setMode(SPI2_SDO, ALTERNATE | ALTERNATE_FUNC(5));
|
||||
gpio_setMode(SPI2_SDI, ALTERNATE | ALTERNATE_FUNC(5));
|
||||
|
||||
spi2_init();
|
||||
spiStm32_init(&spi2, 1300000, 0);
|
||||
|
||||
nvm_init(); /* Initialise non volatile memory manager */
|
||||
toneGen_init(); /* Initialise tone generator */
|
||||
|
|
Ładowanie…
Reference in New Issue