MakingThings
  • Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

can.c

Go to the documentation of this file.
00001 /*********************************************************************************
00002 
00003  Copyright 2006-2008 MakingThings
00004 
00005  Licensed under the Apache License, 
00006  Version 2.0 (the "License"); you may not use this file except in compliance 
00007  with the License. You may obtain a copy of the License at
00008 
00009  http://www.apache.org/licenses/LICENSE-2.0 
00010  
00011  Unless required by applicable law or agreed to in writing, software distributed
00012  under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00013  CONDITIONS OF ANY KIND, either express or implied. See the License for
00014  the specific language governing permissions and limitations under the License.
00015 
00016 *********************************************************************************/
00017 
00018 // MakingThings - Make Controller Board - 2006
00019 
00020 /** \file can.c 
00021   CAN - Control Area Network.
00022   Functions for interacting with the CAN Network.
00023 
00024   Note this subsystem is not implemented
00025 */
00026 
00027 /* Library includes. */
00028 #include <string.h>
00029 #include <stdio.h>
00030 
00031 /* Scheduler includes. */
00032 #include "FreeRTOS.h"
00033 #include "task.h"
00034 #include "semphr.h"
00035 
00036 /* Hardware specific headers. */
00037 #include "Board.h"
00038 #include "AT91SAM7X256.h"
00039 
00040 #include "config.h"
00041 
00042 #include "io.h"
00043 
00044 #include "can.h"
00045 #include "can_internal.h"
00046 
00047 
00048 // CAN DISABLE
00049 #if ( CONTROLLER_VERSION == 50 )
00050   #define CAN_ENABLE IO_PA02
00051   #define CAN_RX     IO_PA19
00052   #define CAN_TX     IO_PA20
00053 #endif
00054 #if ( CONTROLLER_VERSION == 90 )
00055   #define CAN_ENABLE IO_PB16
00056   #define CAN_RX     IO_PA19
00057   #define CAN_TX     IO_PA20
00058 #endif
00059 #if ( CONTROLLER_VERSION == 95 || CONTROLLER_VERSION == 100 )
00060   #define CAN_ENABLE IO_PA07
00061   #define CAN_RX     IO_PA19
00062   #define CAN_TX     IO_PA20
00063 #endif
00064 
00065 static int Can_Start( void );
00066 static int Can_Stop( void );
00067 
00068 static int Can_Init( void );
00069 
00070 extern void ( CanIsr_Wrapper )( void );
00071 
00072 struct Can_ Can;
00073 
00074 /* \defgroup Can
00075 * The CAN (Controller Area Network) subsystem allows for fast and reliable board-to-board communication.
00076 * \ingroup Core
00077 * @{
00078 */
00079 
00080 /**
00081   Sets whether the CAN subsystem is active.
00082   @param state An integer specifying the active state - 1 (on) or 0 (off).
00083   @return 0 on success.
00084 */
00085 int Can_SetActive( int state )
00086 {
00087   if ( state )
00088     return Can_Start( );
00089   else
00090     return Can_Stop( );
00091 }
00092 
00093 /**
00094   Returns the active state of the CAN subsystem.
00095   @return State - 1/non-zero (on) or 0 (off).
00096 */
00097 int Can_GetActive( )
00098 {
00099   return Can.users > 0;
00100 }
00101 
00102 /** 
00103   Send a CAN message.
00104   @param id An integer specifying the message ID.
00105   @param message A pointer to the message to be sent.
00106   @param count ???
00107   @return Status - 0 on success.
00108 */
00109 int Can_SendMessage( int id, char* message, int count )
00110 {
00111   (void)id;
00112   (void)message;
00113   (void)count;
00114 
00115   if ( Can.users < 1 )
00116   {
00117     int status = Can_Start( );
00118     if ( status != CONTROLLER_OK )
00119       return status;
00120   }
00121 
00122   int value = 0;
00123 
00124   int i;
00125   int j;
00126 
00127   for ( i = 0; i < 20; i++ )
00128   {
00129     Io_SetValue( CAN_TX, 1 );
00130     for ( j = 0; j < 100; j++ )
00131       ;
00132     Io_SetValue( CAN_TX, 0 );
00133     for ( j = 0; j < 100; j++ )
00134       ;
00135   }
00136 
00137 /*
00138   // This is the semaphore that lets only one instance get messages at a time
00139   if ( !xSemaphoreTake( Can.semaphore, 1000 ) )
00140     return CONTROLLER_ERROR_CANT_LOCK;
00141 
00142   // start the business
00143 
00144   // Busy wait - nah 
00145   // while ( !( AT91C_BASE_ADC->ADC_CHSR  & ( 1 << index ) ) );
00146 
00147   // This is the semaphore that signals that it's done
00148   if ( !xSemaphoreTake( Can.doneSemaphore, 1000 ) )
00149     return CONTROLLER_ERROR_TIMEOUT;
00150 
00151   // extract the message
00152 
00153   xSemaphoreGive( Can.semaphore );
00154 
00155 
00156  // Disable mailbox 0
00157   AT91C_BASE_CAN->CAN_MB0.CAN_MB_MMR = AT91C_CAN_MOT_DIS;  
00158 
00159     // Set ID to send
00160   AT91C_BASE_CAN->CAN_MB0.CAN_MB_MID = ( ( 0x55 << 18 ) & AT91C_CAN_MIDvA );
00161 
00162  // Set mailbox 0 up as a transmitter
00163   AT91C_BASE_CAN->CAN_MB0.CAN_MB_MMR = AT91C_CAN_MOT_TX;  
00164 
00165   // Set the length, and transmit
00166   AT91C_BASE_CAN->CAN_MB0.CAN_MB_MCR = ( ( 0x4 << 16 ) & AT91C_CAN_MDLC ) || AT91C_CAN_MTCR;
00167 
00168   while ( !AT91C_BASE_CAN->CAN_MB0.CAN_MB_MSR & AT91C_CAN_MRDY )
00169     ;
00170 */
00171   return value;
00172 }
00173 
00174 /** 
00175   Receive a CAN message.
00176   @param id An integer specifying the message ID.
00177   @param message A pointer to where the message should be saved.
00178   @param count ???
00179   @return Status - 0 on success.
00180 */
00181 int Can_GetMessage( int* id, char* message, int* count )
00182 {
00183   (void)id;
00184   (void)message;
00185   (void)count;
00186 
00187   if ( Can.users < 1 )
00188   {
00189     int status = Can_Start( );
00190     if ( status != CONTROLLER_OK )
00191       return status;
00192   }
00193 
00194   int value = 0;
00195 
00196   // This is the semaphore that lets only one instance get messages at a time
00197   if ( !xSemaphoreTake( Can.semaphore, 1000 ) )
00198     return CONTROLLER_ERROR_CANT_LOCK;
00199 
00200   // start the business
00201 
00202   /* Busy wait - nah */
00203   // while ( !( AT91C_BASE_ADC->ADC_CHSR  & ( 1 << index ) ) );
00204 
00205   // This is the semaphore that signals that it's done
00206   if ( !xSemaphoreTake( Can.doneSemaphore, 1000 ) )
00207     return CONTROLLER_ERROR_TIMEOUT;
00208 
00209   // extract the message
00210 
00211   xSemaphoreGive( Can.semaphore );
00212 
00213   return value;
00214 }
00215 
00216 /** @}
00217 */
00218 
00219 int Can_Start()
00220 {
00221   // int status;
00222   if ( Can.users++ == 0 )
00223   {
00224     Can_Init();
00225   }
00226   return CONTROLLER_OK;
00227 }
00228 
00229 int Can_Stop()
00230 {
00231   if ( Can.users <= 0 )
00232     return CONTROLLER_ERROR_TOO_MANY_STOPS;
00233   
00234   if ( --Can.users == 0 )
00235     Can_Stop();
00236 
00237   return CONTROLLER_OK;
00238 }
00239 
00240 int Can_Init()
00241 {
00242   // Try to lock the enable pin
00243   int status = Io_Start( CAN_ENABLE, true );
00244   if ( status != CONTROLLER_OK )
00245     return status;
00246 
00247   // Try to lock the tx pin
00248   status = Io_Start( CAN_TX, true );
00249   if ( status != CONTROLLER_OK )
00250   {
00251     Io_Stop( CAN_ENABLE );
00252     return status;
00253   }
00254 
00255   // Try to lock the rx pin
00256   status = Io_Start( CAN_RX, true );
00257   if ( status != CONTROLLER_OK )
00258   {
00259     Io_Stop( CAN_ENABLE );
00260     Io_Stop( CAN_TX );
00261     return status;
00262   }
00263 
00264   Io_SetDirection( CAN_TX, true );
00265   Io_SetDirection( CAN_RX, false );
00266   Io_SetPullup( CAN_RX, false );
00267 
00268   Io_SetDirection( CAN_ENABLE, true );
00269   Io_SetValue( CAN_ENABLE, false );
00270 
00271 /*
00272   // Enable the peripheral clock
00273   AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_CAN;
00274 
00275   // Make sure the pins are running on the right peripheral (A in this case)
00276   Io_SetPeripheralA( CAN_TX );
00277   Io_SetPeripheralA( CAN_RX );
00278 
00279   Io_SetOutput( CAN_ENABLE );
00280   Io_SetValue( CAN_ENABLE, false );
00281 
00282   // Set some random bit timing up.
00283   AT91C_BASE_CAN->CAN_BR = 0x0053255;
00284     
00285   // Enable the CAN system
00286   AT91C_BASE_CAN->CAN_MR = AT91C_CAN_CANEN;
00287 
00288   // Do the OS stuff
00289   vSemaphoreCreateBinary( Can.semaphore );
00290 
00291   // Create the sempahore that will be used to wake the calling process up 
00292   vSemaphoreCreateBinary( Can.doneSemaphore );
00293   xSemaphoreTake( Can.doneSemaphore, 0 );
00294 
00295   // Do the hardware init
00296 
00297   // Initialize the interrupts
00298 
00299   // WAS AT91F_AIC_ConfigureIt( AT91C_ID_ADC, 3, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) CanIsr_Wrapper );
00300   // Which is defined at the bottom of the AT91SAM7X256.h file
00301   unsigned int mask ;                         
00302                                       
00303   mask = 0x1 << AT91C_ID_CAN;   
00304                         
00305   // Disable the interrupt on the interrupt controller          
00306   AT91C_BASE_AIC->AIC_IDCR = mask ;                   
00307   // Save the interrupt handler routine pointer and the interrupt priority
00308   AT91C_BASE_AIC->AIC_SVR[ AT91C_ID_CAN ] = (unsigned int)CanIsr_Wrapper;     
00309   // Store the Source Mode Register   
00310   AT91C_BASE_AIC->AIC_SMR[ AT91C_ID_CAN ] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 4  ;       
00311   // Clear the interrupt on the interrupt controller
00312   AT91C_BASE_AIC->AIC_ICCR = mask ;         
00313 
00314   // AT91C_BASE_AIC->CAN_IER = 0; // AT91C_ADC_DRDY; 
00315 
00316   AT91C_BASE_AIC->AIC_IECR = mask;
00317 */
00318 
00319   return CONTROLLER_OK;
00320 }
00321 
00322 #ifdef OSC
00323 
00324 #include "osc.h"
00325 #include "string.h"
00326 #include "stdio.h"
00327 
00328 // Need a list of property names
00329 // MUST end in zero
00330 static char* CanOsc_Name = "can";
00331 static char* CanOsc_PropertyNames[] = { "active", "value", 0 }; // must have a trailing 0
00332 
00333 int CanOsc_PropertySet( int property, int value );
00334 int CanOsc_PropertyGet( int property );
00335 
00336 // Returns the name of the subsystem
00337 const char* CanOsc_GetName( )
00338 {
00339   return CanOsc_Name;
00340 }
00341 
00342 // Now getting a message.  This is actually a part message, with the first
00343 // part (the subsystem) already parsed off.
00344 int CanOsc_ReceiveMessage( int channel, char* message, int length )
00345 {
00346   int status = Osc_IntReceiverHelper( channel, message, length, 
00347                                       CanOsc_Name,
00348                                       CanOsc_PropertySet, CanOsc_PropertyGet, 
00349                                       CanOsc_PropertyNames );
00350 
00351   // the can system is complex it will need another kind of helper - one that
00352   // can handle
00353   //     /can/active 1  as well as
00354   //     /can/0/id 21213
00355   // also the can getters and setters will need to be able to handle complex data
00356 
00357   if ( status != CONTROLLER_OK )
00358     return Osc_SendError( channel, CanOsc_Name, status );
00359   return CONTROLLER_OK;
00360 }
00361 
00362 // Set the index LED, property with the value
00363 int CanOsc_PropertySet( int property, int value )
00364 {
00365   switch ( property )
00366   {
00367     case 0: 
00368       Can_SetActive( value );
00369       break;      
00370   }
00371   return CONTROLLER_OK;
00372 }
00373 
00374 // Get the property
00375 int CanOsc_PropertyGet( int property )
00376 {
00377   int value = 0;
00378   switch ( property )
00379   {
00380     case 0:
00381       value = Can_GetActive( );
00382       break;
00383   }
00384   
00385   return value;
00386 }
00387 
00388 #endif // OSC
00389 
00390 
00391 

The Make Controller Kit is an open source project maintained by MakingThings.
MakingThings code is released under the Apache 2.0 license.
Bug tracker, development wiki and status can be found at http://dev.makingthings.com.
This document was last updated on 18 May 2009.