Autor Tema: Distribuyendo el código fuente - LPC1347  (Leído 1824 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Distribuyendo el código fuente - LPC1347
« en: 02 de Octubre de 2014, 20:48:13 »
Si bien es un tema de C en general, lo pongo acá porque se trata de un programa para el LPC1347.

Bien, estamos comenzando a probar código para el POV (http://www.todopic.com.ar/foros/index.php?topic=43414.0) y me gustaría tratar de armarlo lo mejor posible. Tengo esta estructura de archivos:

https://www.dropbox.com/s/0y510tna724fynm/Captura%20de%20pantalla%202014-10-02%2020.40.06.png?dl=0

Como ven tengo por cada .c un .h asociado. Incluso en el principal.c (donde radica el main.c). Esto es correcto? digo, es la forma de hacerlo bien?

Este es el codigo de cada módulo:

principal.h
Código: [Seleccionar]
#ifndef PRINCIPAL_H_
#define PRINCIPAL_H_

#define LATCH_PORT 0 // Port for LATCH
#define LATCH 8 // Bit on port for LATCH

void Delay10useg (uint32_t dlyTicks);

#endif /* PRINCIPAL_H_ */

principal.c

Código: [Seleccionar]
#ifdef __USE_CMSIS
#include "LPC13Uxx.h"
#endif

#include <cr_section_macros.h>

#include "principal.h"
#include "TLC5925.h"
#include "gpio.h"
#include "ssp.h"

volatile uint32_t msTicks;                            /* counts 10us timeTicks */
/*----------------------------------------------------------------------------
  SysTick_Handler
 *----------------------------------------------------------------------------*/
void SysTick_Handler(void) {
  msTicks++;                        /* increment counter necessary in Delay10useg() */
}

/*------------------------------------------------------------------------------
  delays number of tick Systicks (happens every 1 ms)
 *------------------------------------------------------------------------------*/
void Delay10useg (uint32_t dlyTicks) {
uint32_t curTicks;
curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks);
}


int main(void) {
uint16_t data=0;

// Configuramos el SysTick. 72 tick es 1useg. 72.000 ticks es 1msg. 72.000.000 / 100.000
// son 10useg.
if (SysTick_Config(SystemCoreClock / 100000)) {
while (1);
}

GPIOInit(); // Inicializamos el GPIO, hay que habilitar el clock, etc.
SSP0Init(); // Inicializamos el SSP

GPIOSetDir(LATCH_PORT, LATCH, 1); // La señal LATCH es de salida
GPIOSetBitValue( LATCH_PORT, LATCH, 0); // La ponemos en 0


while (1){                                /* Loop forever */
data = 0xAAAA;
SSPSend(&data, 1);
TLC_latch_pulse();
Delay10useg (50);
data = 0x5555;
SSPSend(&data, 1);
TLC_latch_pulse();
Delay10useg (50);
}
}

ssp.h

Código: [Seleccionar]
#ifndef __SSP_H__
#define __SSP_H__

#include "LPC13Uxx.h"

/* There are there modes in SSP: loopback, master or slave. */
/* Here are the combination of all the tests.
(1) LOOPBACK test: LOOPBACK_MODE=1, TX_RX_ONLY=0, USE_CS=1;
(2) Serial EEPROM test: LOOPBACK_MODE=0, TX_RX_ONLY=0, USE_CS=0; (default)
(3) TX(Master) Only: LOOPBACK_MODE=0, SSP_SLAVE=0, TX_RX_ONLY=1, USE_CS=1;
(4) RX(Slave) Only: LOOPBACK_MODE=0, SSP_SLAVE=1, TX_RX_ONLY=0, USE_CS=1 */

#define LOOPBACK_MODE 0 /* 1 is loopback, 0 is normal operation. */
#define SSP_SLAVE 0 /* 1 is SLAVE mode, 0 is master mode */
#define TX_RX_ONLY 0 /* 1 is TX or RX only depending on SSP_SLAVE
flag, 0 is either loopback mode or communicate
with a serial EEPROM. */

/* if USE_CS is zero, set SSEL as GPIO that you have total control of the sequence */
/* When test serial SEEPROM(LOOPBACK_MODE=0, TX_RX_ONLY=0), set USE_CS to 0. */
/* When LOOPBACK_MODE=1 or TX_RX_ONLY=1, set USE_CS to 1. */

#define USE_CS 0

/* SPI read and write buffer size */
#define SSP_BUFSIZE 16
#define FIFOSIZE 8

#define DELAY_COUNT 10
#define MAX_TIMEOUT 0xFF

/* Port0.2 is the SSP select pin */
#define SSP0_SEL (1 << 2)

/* SSP Status register */
#define SSPSR_TFE (1 << 0)
#define SSPSR_TNF (1 << 1)
#define SSPSR_RNE (1 << 2)
#define SSPSR_RFF (1 << 3)
#define SSPSR_BSY (1 << 4)

/* SSP CR0 register */
#define SSPCR0_DSS (1 << 0)
#define SSPCR0_FRF (1 << 4)
#define SSPCR0_SPO (1 << 6)
#define SSPCR0_SPH (1 << 7)
#define SSPCR0_SCR (1 << 8)

/* SSP CR1 register */
#define SSPCR1_LBM (1 << 0)
#define SSPCR1_SSE (1 << 1)
#define SSPCR1_MS (1 << 2)
#define SSPCR1_SOD (1 << 3)

/* SSP Interrupt Mask Set/Clear register */
#define SSPIMSC_RORIM (1 << 0)
#define SSPIMSC_RTIM (1 << 1)
#define SSPIMSC_RXIM (1 << 2)
#define SSPIMSC_TXIM (1 << 3)

/* SSP0 Interrupt Status register */
#define SSPRIS_RORRIS (1 << 0)
#define SSPRIS_RTRIS (1 << 1)
#define SSPRIS_RXRIS (1 << 2)
#define SSPRIS_TXRIS (1 << 3)

/* SSP0 Masked Interrupt register */
#define SSPMIS_RORMIS (1 << 0)
#define SSPMIS_RTMIS (1 << 1)
#define SSPMIS_RXMIS (1 << 2)
#define SSPMIS_TXMIS (1 << 3)

/* SSP0 Interrupt clear register */
#define SSPICR_RORIC (1 << 0)
#define SSPICR_RTIC (1 << 1)

/* RDSR status bit definition */
#define RDSR_RDY 0x01
#define RDSR_WEN 0x02

/* If RX_INTERRUPT is enabled, the SSP RX will be handled in the ISR
SSPReceive() will not be needed. */
extern void SSP0Init( void );
void SSPSend(uint16_t *buf, uint32_t Length );
extern void SSP0_IRQHandler(void);

#endif  /* __SSP_H__ */
/*****************************************************************************
**                            End Of File
******************************************************************************/

ssp.c

Código: [Seleccionar]
/****************************************************************************
 *   $Id:: ssp.c 5804 2010-12-04 00:32:12Z usb00423                         $
 *   Project: NXP LPC17xx SSP example
 *
 *   Description:
 *     This file contains SSP code example which include SSP initialization,
 *     SSP interrupt handler, and APIs for SSP access.
 *
 ****************************************************************************/

#include "LPC13Uxx.h" /* LPC17xx Peripheral Registers */
#include "ssp.h"

/* statistics of all the interrupts */
volatile uint32_t interrupt0RxStat = 0;
volatile uint32_t interrupt0OverRunStat = 0;
volatile uint32_t interrupt0RxTimeoutStat = 0;


/*****************************************************************************
** Function name: SSP_IRQHandler
**
** Descriptions: SSP port is used for SPI communication.
** SSP interrupt handler
** The algorithm is, if RXFIFO is at least half full,
** start receive until it's empty; if TXFIFO is at least
** half empty, start transmit until it's full.
** This will maximize the use of both FIFOs and performance.
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void SSP0_IRQHandler(void)
{
  uint32_t regValue;

  regValue = LPC_SSP0->MIS;
  if ( regValue & SSPMIS_RORMIS ) /* Receive overrun interrupt */
  {
interrupt0OverRunStat++;
LPC_SSP0->ICR = SSPICR_RORIC; /* clear interrupt */
  }
  if ( regValue & SSPMIS_RTMIS ) /* Receive timeout interrupt */
  {
interrupt0RxTimeoutStat++;
LPC_SSP0->ICR = SSPICR_RTIC; /* clear interrupt */
  }

  /* please be aware that, in main and ISR, CurrentRxIndex and CurrentTxIndex
  are shared as global variables. It may create some race condition that main
  and ISR manipulate these variables at the same time. SSPSR_BSY checking (polling)
  in both main and ISR could prevent this kind of race condition */
  if ( regValue & SSPMIS_RXMIS ) /* Rx at least half full */
  {
interrupt0RxStat++; /* receive until it's empty */
  }
  return;
}


/*****************************************************************************
** Function name: SSPInit
**
** Descriptions: SSP port initialization routine
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void SSP0Init( void )
{
//  uint8_t i, Dummy=Dummy;

LPC_SYSCON->PRESETCTRL |= 1; // Des reseteamos el SSP0

LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11); //Damos alimentacion al módulo SPP0

  LPC_SYSCON->SSP0CLKDIV = 36; // Ponemos el PCLK del SSP0 a 2MHz

  /* P0.6 SCK; P0.9 MOSI */
  LPC_IOCON->PIO0_9 = 1; // Elejimos la funcion MOSI0
  LPC_IOCON->PIO0_6 = 2; // Elejimos la funcion SCK0

  LPC_GPIO->DIR[0] |= ((1<<9) | (1<<6)); // PIO0.9 y PIO0.6 como salida

  /* Set DSS data to 16-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 7+1 */
  LPC_SSP0->CR0 = 0xF;

  /* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
  LPC_SSP0->CPSR = 0x2;

  /* Enable the SSP Interrupt */
  NVIC_EnableIRQ(SSP0_IRQn);

  /* Device select as master, SSP Enabled */
  /* Master mode */
  LPC_SSP0->CR1 = 2;

  /* Set SSPINMS registers to enable interrupts */
  /* enable all error related interrupts */
  LPC_SSP0->IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM;
  return;
}

/*****************************************************************************
** Function name: SSPSend
**
** Descriptions: Send a block of data to the SSP port, the
** first parameter is the buffer pointer, the 2nd
** parameter is the block length.
**
** parameters: buffer pointer, and the block length
** Returned value: None
**
*****************************************************************************/
void SSPSend(uint16_t *buf, uint32_t Length ){
uint32_t i;
uint8_t Dummy = Dummy;

for ( i = 0; i < Length; i++ ){
/* Move on only if NOT busy and TX FIFO not full. */
while ( (LPC_SSP0->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF );
LPC_SSP0->DR = *buf;
buf++;
/* Wait until the Busy bit is cleared. */
while ( LPC_SSP0->SR & SSPSR_BSY );
}
return;
}
/******************************************************************************
**                            End Of File
******************************************************************************/

tlc5925.h

Código: [Seleccionar]
#ifndef TLC5925_H_
#define TLC5925_H_

void TLC_latch_pulse();
extern void Delay10useg (uint32_t dlyTicks);

#endif /* TLC5925_H_ */

tlc5925.c

Código: [Seleccionar]
#include "LPC13Uxx.h"
#include "gpio.h"
#include "TLC5925.h"
#include "principal.h"



void TLC_latch_pulse(){
GPIOSetBitValue(LATCH_PORT, LATCH, 1);
Delay10useg(1);
GPIOSetBitValue(LATCH_PORT, LATCH, 0);
}

El tema de los define en los .h y luego los includes en los .c lo estoy manejando bien?
Por ejemplo, en principal.h tengo
Código: [Seleccionar]
#define LATCH_PORT 0 // Port for LATCHque luego uso en tlc5925.c y en principal.c

Otra duda es, en los programas de ejemplo la funcion delay esta hecha de esta forma:

Código: [Seleccionar]
/*------------------------------------------------------------------------------
  delays number of tick Systicks (happens every 1 ms)
 *------------------------------------------------------------------------------*/
__INLINE static void Delay (uint32_t dlyTicks) {
  uint32_t curTicks;

  curTicks = msTicks;
  while ((msTicks - curTicks) < dlyTicks);
}

pero si la dejo así, como hago para usarla en otros .c?

lo que yo hice fue sacarle el INLINE y el static, así funciona con extern en los otros .c, pero no sé si al sacarle el static no estoy haciendo cagada...

aguardo comentarios!

Saludos
-
Leonardo Garberoglio


 

anything