mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-19 00:13:21 +08:00
修改了Web后台的部分界面,增加了HAmqtt中的总电量传感器,后台新增mqtt上报频率设置
This commit is contained in:
451
mico-os/platform/MCU/LPC5410x/peripherals/platform_spi.c
Normal file
451
mico-os/platform/MCU/LPC5410x/peripherals/platform_spi.c
Normal file
@@ -0,0 +1,451 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file MicoDriverSpi.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide SPI driver functions.
|
||||
******************************************************************************
|
||||
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||||
* Copyright (c) 2016 MXCHIP Inc.
|
||||
*
|
||||
* The contents of this file may not be disclosed to third parties, copied or
|
||||
* duplicated in any form, in whole or in part, without the prior written
|
||||
* permission of MXCHIP Corporation.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "mico_platform.h"
|
||||
#include "mico_rtos.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "platform_config.h"
|
||||
#include "platform_peripheral.h"
|
||||
#include "debug.h"
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
#define MAX_NUM_SPI_PRESCALERS (8)
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Static Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
uint8_t platform_spi_get_port_number( platform_spi_port_t* spi )
|
||||
{
|
||||
if ( spi == LPC_SPI0 ) {
|
||||
return 0;
|
||||
}
|
||||
else if ( spi == LPC_SPI1 ) {
|
||||
return 1;
|
||||
}
|
||||
// else if ( spi == LPC_SPI2 ) {
|
||||
// return 2;
|
||||
// }
|
||||
else if ( spi == NULL ) {
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
#define SPI_FLASH_CS_LOW Chip_GPIO_SetPinState(LPC_GPIO, 0, 14, 0)
|
||||
#define SPI_FLASH_CS_HIGH Chip_GPIO_SetPinState(LPC_GPIO, 0, 14, 1)
|
||||
//
|
||||
#define SPI_FLASH_MISO_LOW
|
||||
#define SPI_FLASH_MISO_HIGH
|
||||
|
||||
#define SPI_FLASH_MISO_GET Chip_GPIO_GetPinState(LPC_GPIO, 0, 13)
|
||||
|
||||
#define SPI_FLASH_MOSI_LOW Chip_GPIO_SetPinState(LPC_GPIO, 0, 12, 0)
|
||||
#define SPI_FLASH_MOSI_HIGH Chip_GPIO_SetPinState(LPC_GPIO, 0, 12, 1)
|
||||
|
||||
#define SPI_FLASH_SCK_LOW Chip_GPIO_SetPinState(LPC_GPIO, 0, 11, 0)
|
||||
#define SPI_FLASH_SCK_HIGH Chip_GPIO_SetPinState(LPC_GPIO, 0, 11, 1)
|
||||
|
||||
// Magicoe OSStatus platform_spi_init( const platform_spi_t* spi, const platform_spi_config_t* config )
|
||||
OSStatus platform_spi_init( platform_spi_driver_t* driver, const platform_spi_t* peripheral, const platform_spi_config_t* config )
|
||||
{
|
||||
// SPI_InitTypeDef spi_init;
|
||||
OSStatus err = kNoErr;
|
||||
platform_mcu_powersave_disable();
|
||||
uint32_t t1; //general var
|
||||
require_action_quiet( ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);
|
||||
|
||||
require_action_quiet( ( peripheral->port == LPC_SPI0 ), exit, err = kParamErr);
|
||||
|
||||
|
||||
driver->isRxDone = driver->isTxDone = 0;
|
||||
#ifndef NO_MICO_RTOS
|
||||
if (driver->sem_xfer_done == 0)
|
||||
mico_rtos_init_semaphore(&driver->sem_xfer_done, 1);
|
||||
#endif
|
||||
|
||||
// >>> Init Pin mux
|
||||
t1 = IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF;
|
||||
|
||||
if (peripheral->port == LPC_SPI0)
|
||||
{
|
||||
if (config->speed >= 24000000)
|
||||
t1 |= 1UL<<9; // enable fast slew
|
||||
g_pIO->PIO[0][11] = IOCON_FUNC1 | t1;/* SPI0_SCK */
|
||||
g_pIO->PIO[0][12] = IOCON_FUNC1 | t1; /* SPI0_MOSI */
|
||||
g_pIO->PIO[0][13] = IOCON_FUNC1 | t1; /* SPI0_MISO */
|
||||
// config CS pin as GPIO
|
||||
g_pIO->PIO[config->chip_select->port][config->chip_select->pin_number] = IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF;
|
||||
platform_gpio_output_high(config->chip_select);
|
||||
platform_gpio_init(config->chip_select, OUTPUT_PUSH_PULL);
|
||||
}
|
||||
// <<<
|
||||
|
||||
// >>>
|
||||
// initialize SPI peripheral
|
||||
{
|
||||
uint32_t bv;
|
||||
LPC_SPI_T *pSPI = peripheral->port;
|
||||
|
||||
// >>>
|
||||
bv = pSPI == LPC_SPI0 ? 1UL << 9 : 1UL<<10;
|
||||
|
||||
g_pASys->ASYNCAPBCLKCTRLSET = bv; // enable clock to SPI
|
||||
|
||||
g_pASys->ASYNCPRESETCTRLSET = bv;
|
||||
g_pASys->ASYNCPRESETCTRLCLR = bv;
|
||||
// <<<
|
||||
|
||||
// predly | postDly| fraDly | xferDly
|
||||
pSPI->DLY = 1UL<<0 | 1UL<<4 | 1UL<<8 | 1UL<<12;
|
||||
pSPI->DLY = 0;
|
||||
|
||||
t1 = Chip_Clock_GetAsyncSyscon_ClockRate();
|
||||
t1 = (t1 + config->speed - 1) / config->speed;
|
||||
pSPI->DIV = t1 - 1; // proper division
|
||||
|
||||
pSPI->TXCTRL = (config->bits - 1) << 24; // 8 bits per frame
|
||||
|
||||
// Enable | master | no loopback
|
||||
t1 = 1UL<<0 | 1UL<<2 | 0UL<<7;
|
||||
// determine SPI mode
|
||||
if (config->mode & SPI_CLOCK_IDLE_HIGH) {
|
||||
t1 |= 1UL<<5; // CPOL = 1
|
||||
if (t1 & SPI_CLOCK_RISING_EDGE)
|
||||
t1 |= 1UL<<4; // CPHA = 1
|
||||
} else {
|
||||
if (!(t1 & SPI_CLOCK_RISING_EDGE))
|
||||
t1 |= 1UL<<4;
|
||||
}
|
||||
pSPI->CFG = t1;
|
||||
}
|
||||
// <<<
|
||||
|
||||
g_pDMA->DMACOMMON[0].ENABLESET = (1UL<<peripheral->dmaRxChnNdx) | (1UL<<peripheral->dmaTxChnNdx);
|
||||
g_pDMA->DMACOMMON[0].INTENSET = (1UL<<peripheral->dmaRxChnNdx) | (1UL<<peripheral->dmaTxChnNdx);
|
||||
|
||||
g_pDMA->DMACH[peripheral->dmaRxChnNdx].CFG = DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGBURST_SNGL | DMA_CFG_CHPRIORITY(1);
|
||||
g_pDMA->DMACH[peripheral->dmaTxChnNdx].CFG = DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGBURST_SNGL | DMA_CFG_CHPRIORITY(1);
|
||||
|
||||
exit:
|
||||
platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Magicoe OSStatus platform_spi_deinit( const platform_spi_t* spi )
|
||||
OSStatus platform_spi_deinit( platform_spi_driver_t* driver )
|
||||
{
|
||||
uint32_t bv;
|
||||
OSStatus err = kNoErr;
|
||||
platform_spi_t const *peripheral;;
|
||||
LPC_SPI_T *pSPI;
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( driver->peripheral != NULL ), exit, err = kParamErr);
|
||||
|
||||
peripheral = driver->peripheral , pSPI = peripheral->port;
|
||||
|
||||
bv = pSPI == LPC_SPI0 ? 1UL << 9 : 1UL<<10;
|
||||
|
||||
g_pASys->ASYNCAPBCLKCTRLCLR = bv; // disable clock to SPI
|
||||
g_pASys->ASYNCPRESETCTRLSET = bv; // put SPI into reset state
|
||||
|
||||
// disable DMA channels for SPI
|
||||
g_pDMA->DMACOMMON[0].ENABLECLR = (1UL<<peripheral->dmaRxChnNdx) | (1UL<<peripheral->dmaTxChnNdx);
|
||||
g_pDMA->DMACOMMON[0].INTENCLR = (1UL<<peripheral->dmaRxChnNdx) | (1UL<<peripheral->dmaTxChnNdx);
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
if (driver->sem_xfer_done != 0)
|
||||
mico_rtos_deinit_semaphore(&driver->sem_xfer_done);
|
||||
driver->sem_xfer_done = 0;
|
||||
#endif
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*static*/ platform_spi_driver_t *s_pSPIDrvs[1];
|
||||
void OnSPIDmaXferDone(uint32_t spiNdx, uint32_t isRx, uint32_t isErr)
|
||||
{
|
||||
platform_spi_driver_t *pDrv = s_pSPIDrvs[spiNdx];
|
||||
if (isRx) {
|
||||
pDrv->isRxDone = 1;
|
||||
if (isErr)
|
||||
pDrv->xferErr |= 1UL<<1;
|
||||
} else {
|
||||
pDrv->isTxDone = 1;
|
||||
if (isErr)
|
||||
pDrv->xferErr |= 1UL<<0;
|
||||
}
|
||||
#ifndef NO_MICO_RTOS
|
||||
if (pDrv->isTxDone) {
|
||||
if (!pDrv->isRx || pDrv->isRxDone)
|
||||
mico_rtos_set_semaphore(&pDrv->sem_xfer_done);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Magicoe OSStatus platform_spi_transfer( const platform_spi_t* spi, const platform_spi_config_t* config, const platform_spi_message_segment_t* segments, uint16_t number_of_segments )
|
||||
OSStatus platform_spi_transfer( platform_spi_driver_t* driver, const platform_spi_config_t* config, const platform_spi_message_segment_t* segments, uint16_t number_of_segments )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
uint32_t count = 0;
|
||||
uint32_t i;
|
||||
const platform_spi_message_segment_t *pSeg;
|
||||
uint32_t dmaXferLen;
|
||||
DMA_CHDESC_T *pTxDesc, *pRxDesc;
|
||||
LPC_SPI_T *pSPI;
|
||||
uint32_t dmaRxChnNdx, dmaTxChnNdx;
|
||||
|
||||
const uint8_t *pcTx;
|
||||
uint8_t *pRx;
|
||||
|
||||
require_action_quiet( ( driver != NULL ) && ( config != NULL ) && ( segments != NULL ) && ( number_of_segments != 0 ), exit, err = kParamErr);
|
||||
|
||||
// save the driver pointer so that in DMA IRQ callback we can access its members
|
||||
|
||||
|
||||
platform_mcu_powersave_disable();
|
||||
|
||||
pSeg = segments;
|
||||
pTxDesc = (DMA_CHDESC_T *) g_pDMA->SRAMBASE + driver->peripheral->dmaTxChnNdx;
|
||||
pRxDesc = (DMA_CHDESC_T *) g_pDMA->SRAMBASE + driver->peripheral->dmaRxChnNdx;
|
||||
pSPI = driver->peripheral->port;
|
||||
if (pSPI == LPC_SPI0)
|
||||
s_pSPIDrvs[0] = driver;
|
||||
dmaRxChnNdx = driver->peripheral->dmaRxChnNdx , dmaTxChnNdx = driver->peripheral->dmaTxChnNdx;
|
||||
driver->xferErr = 0;
|
||||
/* Activate chip select */
|
||||
platform_gpio_output_low( config->chip_select );
|
||||
for ( i = 0; i < number_of_segments; i++, pSeg++ )
|
||||
{
|
||||
// transfer one seg
|
||||
count = pSeg->length;
|
||||
if (0 == count)
|
||||
continue;
|
||||
|
||||
pcTx = pSeg->tx_buffer , pRx = pSeg->rx_buffer;
|
||||
|
||||
do
|
||||
{
|
||||
dmaXferLen = count > DMA_MAX_XFER_CNT ? DMA_MAX_XFER_CNT : count;
|
||||
count -= dmaXferLen;
|
||||
driver->isRxDone = driver->isTxDone = 0;
|
||||
#if 0
|
||||
{
|
||||
if (pRx != 0)
|
||||
{
|
||||
pSPI->TXCTRL &= ~(1UL<<22);
|
||||
if (pSPI->STAT & SPI_STAT_RXRDY)
|
||||
pSPI->RXDAT;
|
||||
while (dmaXferLen--)
|
||||
{
|
||||
while (!(pSPI->STAT & SPI_STAT_TXRDY));
|
||||
pSPI->TXDAT = *pcTx++;
|
||||
while (!(pSPI->STAT & SPI_STAT_RXRDY));
|
||||
*pRx++ = (uint8_t) pSPI->RXDAT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pSPI->TXCTRL |= (1UL<<22);
|
||||
while (dmaXferLen--)
|
||||
{
|
||||
while (!(pSPI->STAT & SPI_STAT_TXRDY));
|
||||
pSPI->TXDAT = *pcTx++;
|
||||
}
|
||||
}
|
||||
|
||||
while (!(pSPI->STAT & SPI_STAT_TXRDY));
|
||||
}
|
||||
#else
|
||||
pTxDesc->next = 0;
|
||||
pTxDesc->dest = DMA_ADDR(&pSPI->TXDAT);
|
||||
pTxDesc->source = DMA_ADDR(pcTx) + dmaXferLen - 1;
|
||||
pTxDesc->xfercfg = DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA |
|
||||
DMA_XFERCFG_SWTRIG | DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_SRCINC_1 |
|
||||
DMA_XFERCFG_DSTINC_0 | DMA_XFERCFG_XFERCOUNT(dmaXferLen);
|
||||
|
||||
if (pRx != 0)
|
||||
{
|
||||
pSPI->TXCTRL &= ~(1UL<<22);
|
||||
driver->isRx = 1;
|
||||
pRxDesc->next = 0;
|
||||
pRxDesc->source = DMA_ADDR(&pSPI->RXDAT);
|
||||
pRxDesc->dest = DMA_ADDR(pRx) + dmaXferLen - 1;
|
||||
pRxDesc->xfercfg = DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA |
|
||||
DMA_XFERCFG_SWTRIG | DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_DSTINC_1 |
|
||||
DMA_XFERCFG_SRCINC_0 | DMA_XFERCFG_XFERCOUNT(dmaXferLen);
|
||||
|
||||
// start RX DMA
|
||||
g_pDMA->DMACH[dmaRxChnNdx].XFERCFG = pRxDesc->xfercfg;
|
||||
} else {
|
||||
driver->isRx = 0;
|
||||
pSPI->TXCTRL |= (1UL<<22);
|
||||
}
|
||||
|
||||
// start TX DMA
|
||||
g_pDMA->DMACH[dmaTxChnNdx].XFERCFG = pTxDesc->xfercfg;
|
||||
|
||||
|
||||
|
||||
#ifndef NO_MICO_RTOS
|
||||
mico_rtos_get_semaphore(&driver->sem_xfer_done, MICO_WAIT_FOREVER);
|
||||
#else
|
||||
while(1)
|
||||
{
|
||||
if (driver->isTxDone)
|
||||
{
|
||||
if (!driver->isRx || driver->isRxDone)
|
||||
break;
|
||||
}
|
||||
// __WFI();
|
||||
mico_rtos_delay_milliseconds(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
if (driver->xferErr)
|
||||
{
|
||||
err = kGeneralErr;
|
||||
break;
|
||||
}
|
||||
// >>> update read and/or write pointers
|
||||
pcTx += dmaXferLen;
|
||||
if (pRx != 0)
|
||||
pRx += dmaXferLen;
|
||||
// <<<
|
||||
} while (count);
|
||||
}
|
||||
platform_gpio_output_high( config->chip_select );
|
||||
exit:
|
||||
|
||||
|
||||
platform_mcu_powersave_enable( );
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
uint8_t SPI_SendData(uint8_t data)
|
||||
{
|
||||
uint32_t i = 0, j = 0;
|
||||
uint8_t ret = 0;
|
||||
|
||||
for(i=0; i<8; i++) {
|
||||
ret = ((ret<<1)&0xFE);
|
||||
SPI_FLASH_SCK_LOW;
|
||||
for(j=0; j<10; j++);
|
||||
if(data&0x80) {
|
||||
SPI_FLASH_MOSI_HIGH;
|
||||
}
|
||||
else{
|
||||
SPI_FLASH_MOSI_LOW;
|
||||
}
|
||||
for(j=0; j<10; j++);
|
||||
SPI_FLASH_SCK_HIGH;
|
||||
for(j=0; j<10; j++);
|
||||
data = (data<<1);
|
||||
if((SPI_FLASH_MISO_GET&0x01) == 1) {
|
||||
ret = ret|0x01;
|
||||
}
|
||||
else {
|
||||
ret &= 0xFE;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
//
|
||||
//static uint16_t spi_transfer( const platform_spi_t* spi, uint16_t data )
|
||||
//{
|
||||
// uint16_t ret = 0;
|
||||
// ret = SPI_SendData(data);
|
||||
//// printf("SPI RW %x %x\r\n", tmp, ret);
|
||||
// return ret;
|
||||
//}
|
||||
|
||||
platform_spi_message_segment_t s_segs[3];
|
||||
#if 0
|
||||
#pragma data_alignment=16
|
||||
uint8_t s_spiTestbuf[3200];
|
||||
|
||||
extern const mico_spi_device_t mico_spi_flash;
|
||||
extern platform_spi_driver_t platform_spi_drivers[];
|
||||
extern const platform_gpio_t platform_gpio_pins[];
|
||||
|
||||
void SPIDrvTest(void)
|
||||
{
|
||||
platform_spi_config_t cfg;
|
||||
s_segs[0].length = 1024;
|
||||
s_segs[0].tx_buffer = (const void*) 0;
|
||||
s_segs[0].rx_buffer = s_spiTestbuf;
|
||||
|
||||
s_segs[1].length = 1025;
|
||||
s_segs[1].tx_buffer = (const void*) 0x1000;
|
||||
s_segs[1].rx_buffer = s_spiTestbuf;
|
||||
|
||||
s_segs[2].length = sizeof(s_spiTestbuf);
|
||||
s_segs[2].tx_buffer = (const void*) 0x4000;
|
||||
s_segs[2].rx_buffer = s_spiTestbuf;
|
||||
|
||||
cfg.speed = mico_spi_flash.speed;
|
||||
cfg.chip_select = platform_gpio_pins + mico_spi_flash.chip_select;
|
||||
cfg.mode = mico_spi_flash.mode;
|
||||
cfg.bits = mico_spi_flash.bits;
|
||||
|
||||
// >>>
|
||||
{
|
||||
|
||||
platform_spi_driver_t *pDrv = &platform_spi_drivers[MICO_SPI_0];
|
||||
platform_spi_t const *pHw = pDrv->peripheral;
|
||||
platform_spi_init(pDrv, pHw, &cfg);
|
||||
platform_spi_deinit(pDrv);
|
||||
platform_spi_init(pDrv, pHw, &cfg);
|
||||
g_pSPI0->CFG |= 1UL << 7;
|
||||
platform_spi_transfer(pDrv, &cfg, s_segs + 0, 3);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void SPIDrvTest(void) {}
|
||||
#endif
|
||||
|
||||
// end file --- MG.Niu ---
|
||||
Reference in New Issue
Block a user